Java: Как вы конвертируете временную метку UTC в локальное время?

У меня есть отметка времени в UTC, и я хочу преобразовать ее в локальное время без использования вызова API, такого как TimeZone.getTimeZone("PST") . Как именно вы должны это делать? Я использовал следующий код без особого успеха:

 private static final SimpleDateFormat mSegmentStartTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); Calendar calendar = Calendar.getInstance(); try { calendar.setTime(mSegmentStartTimeFormatter.parse(startTime)); } catch (ParseException e) { e.printStackTrace(); } return calendar.getTimeInMillis(); промежуток private static final SimpleDateFormat mSegmentStartTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); Calendar calendar = Calendar.getInstance(); try { calendar.setTime(mSegmentStartTimeFormatter.parse(startTime)); } catch (ParseException e) { e.printStackTrace(); } return calendar.getTimeInMillis(); 

Пример входного значения: [2012-08-15T22:56:02.038Z]

должен вернуть эквивалент [2012-08-15T15:56:02.038Z]

Date не имеет часовой пояс и внутренне хранится в UTC. Только при форматировании даты применяется коррекция часового пояса. При использовании DateFormat умолчанию используется часовой пояс JVM, в котором он запущен. Используйте setTimeZone чтобы изменить его при необходимости.

 DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); utcFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = utcFormat.parse("2012-08-15T22:56:02.038Z"); DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); pstFormat.setTimeZone(TimeZone.getTimeZone("PST")); System.out.println(pstFormat.format(date)); 

Это печатает 2012-08-15T15:56:02.038

Обратите внимание, что я оставил 'Z' в формате PST, так как он указывает UTC. Если вы только что пошли с Z то выход будет 2012-08-15T15:56:02.038-0700

Используйте современный API дат и времени Java, и это просто:

  String inputValue = "2012-08-15T22:56:02.038Z"; Instant timestamp = Instant.parse(inputValue); ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles")); System.out.println(losAngelesTime); 

Это печатает

 2012-08-15T15:56:02.038-07:00[America/Los_Angeles] 

Следует отметить:

  • В ваших ожиданиях есть небольшая ошибка. Z в вашей временной отметке означает UTC, также известный как время Зулу. Поэтому в вашем местном значении времени Z не должен быть там. Скорее вам нужно получить возвращаемое значение, например, 2012-08-15T15:56:02.038-07:00 , так как смещение теперь составляет -7 часов, а не Z.
  • Избегайте трех буквенных сокращений. Они не стандартизированы и, следовательно, чаще всего неоднозначны. PST, например, может означать стандартное время Philppine, стандартное время в Pacific Standard или стандартное время Pitcairn (хотя S в аббревиатуре часто используется для летнего времени (что означает DST)). Если вы планируете использовать «Стандартное время по тихоокеанскому времени», это даже не часовой пояс, так как летом (где падает временная отметка вашего образца) используется «Тихоокеанское дневное время». Вместо аббревиатур используются идентификаторы часовых поясов в формате region / city, как в моем коде.
  • Временные метки обычно лучше всего обрабатываются как объекты Instant . Преобразуйте в ZonedDateTime только тогда, когда вам нужно, например, для презентации.

Вопрос: Можно ли использовать современный API с моей версией Java?

Если вы используете хотя бы Java 6 , вы можете.

  • В Java 8 и более поздних версиях появился новый API.
  • В Java 6 и 7 вы получите ThreeTen Backport , backport из новых classов (это ThreeTen для JSR-310, где впервые был определен современный API).
  • На Android используйте версию Android ThreeTen Backport. Это называется ThreeTenABP, и я думаю, что в этом вопросе есть замечательное объяснение : как использовать ThreeTenABP в Android Project .

Вот простое модифицированное решение

  public String convertToCurrentTimeZone(String Date) { String converted_date = ""; try { DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); utcFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date date = utcFormat.parse(Date); DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone())); converted_date = currentTFormat.format(date); }catch (Exception e){ e.printStackTrace();} return converted_date; } //get the current time zone public String getCurrentTimeZone(){ TimeZone tz = Calendar.getInstance().getTimeZone(); System.out.println(tz.getDisplayName()); return tz.getID(); } 
  • linux конвертировать время (для разных часовых поясов) в UTC
  • Мне нужен список сопоставлений городов для timezones - лучший способ получить его?
  • Веб-сервис - текущий часовой пояс для города?
  • Как хранить дату и время и временные метки в часовом поясе UTC с JPA и Hibernate
  • Как элегантно работать с часовыми поясами
  • Как обрабатывать календарные часовые пояса с помощью Java?
  • Установите системный часовой пояс из .NET.
  • Как установить часовой пояс по умолчанию в node.js?
  • Изменение часового пояса MySQL?
  • Как перевести между часовыми поясами Windows и IANA?
  • iOS: конвертировать UTC NSDate в локальный часовой пояс
  • Давайте будем гением компьютера.