Как преобразовать значение даты и времени со смещением UTC в GMT в Java 7

У меня есть значение даты и времени 2016-12-21T07:48:36 со смещением UTC+14. Как преобразовать дату и время в эквивалентное стандартное время по Гринвичу.

Я пытался использовать метод sampleDateFormat.parse(). Но я не могу получить объект TimeZone для смещения UTC, например.

sampleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC+14:00"))

Пожалуйста, помогите мне преобразовать дату и время UTC в стандартное время по Гринвичу в Java 7.


person GOPI    schedule 21.12.2016    source источник
comment
Вы знаете, что ваша проблема только в том, что вы использовали неподдерживаемый формат UTC+14. getTimeZone знает только форму GMT+xx   -  person Sxilderik    schedule 22.12.2016
comment
Откуда вы взяли смещение +14?   -  person IgorGanapolsky    schedule 20.02.2018


Ответы (3)


Я предполагаю, что у вас есть исходная дата в виде строки. Сделайте следующее:

  • Создайте SimpleDateFormat и установите часовой пояс на «GMT+14».
  • Разобрать строковое значение. Вы получаете объект Date
  • Установите часовой пояс SimpleDateFormat на «UTC» (или используйте другой экземпляр SimpleDateFormat)
  • Отформатируйте дату (если вы хотите, чтобы результат был также строкой)

Пример:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class ConvertToUTC {
  public static void main(String[] args) throws Exception {

      String dateval = "2016-12-21T07:48:36";
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
      df.setTimeZone(TimeZone.getTimeZone("GMT+14"));
      Date date = df.parse(dateval);

      System.out.println(df.format(date)); // GMT+14

      df.setTimeZone(TimeZone.getTimeZone("UTC"));
      System.out.println(df.format(date)); // UTC
  }
}
person Grodriguez    schedule 21.12.2016
comment
Будет ли учитываться компонент перехода на летнее время, если мы используем GMT+смещение вместо UTC+смещение? - person GOPI; 21.12.2016
comment
@GOPI Ответ правильный. В вашем вопросе упоминаются только фиксированные смещения (и они равны, если префикс GMT или UTC). Таким образом, переход на летнее время не имеет значения в контексте вашего вопроса. В противном случае не используйте фиксированные смещения, а используйте идентификаторы часовых поясов, такие как Азия/Токио и т. д. - person Meno Hochschild; 21.12.2016
comment
Спасибо, Мено и Гродригес! - person GOPI; 22.12.2016

используйте "GMT+14:00" вместо "UTC+14:00"

SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("GMT+14:00"));
final Date d = f.parse("2016-12-21T07:48:36");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(d)); // -> 2016-12-20T05:48:36
person Sxilderik    schedule 21.12.2016

tl;dr

LocalDateTime.parse( "2016-12-21T07:48:36" )        // Parse as a `LocalDateTime` given the lack of an offset or zone. *Not* an actual moment, only a rough approximation of potential moments along a range of about 26-27 hours.
             .atOffset( ZoneOffset.ofHours( 14 ) )  // Assign an offset-from-UTC as context, giving meaning to determine an actual point on the timeline.
             .toInstant()                           // Renders `Instant` object in UTC.

Java.время

Современный способ — это классы java.time, встроенные в Java 8 и более поздние версии. Большая часть функций обратно перенесена на Java 6 и 7 в ThreeTen-Backport. проект.

ZoneOffset offset = ZoneOffset.ofHours( 14 ); // fourteen hours ahead of UTC.

Разберите строку как LocalDateTime, поскольку она отсутствует какая-либо информация о смещении или зоне. Вводимые данные представлены в стандартном формате ISO 8601, поэтому шаблон форматирования указывать не нужно.

LocalDateTime ldt = LocalDateTime.parse( "2016-12-21T07:48:36" );

Примените смещение к локальной дате и времени, чтобы получить OffsetDateTime объект.

OffsetDateTime odt = ldt.atOffset( offset );

Из него извлеките Instant, который всегда находится в UTC.

Instant instant = odt.toInstant();

Instant.toString(): 2016-12-20T17:48:36Z

В UTC значением является другая дата, 20-е вместо 21-го.

См. действующий код на сайте IdeOne.com.


О java.time

java.time встроена в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

Использование драйвера JDBC, совместимого с JDBC 4.2 или более поздней версии вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Нет необходимости ни в строках, ни в классах java.sql.*.

Где получить классы java.time?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. . Этот проект является испытательным полигоном для возможных дополнений к java.time в будущем. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и подробнее.

person Basil Bourque    schedule 21.12.2016
comment
Технически Instant не находится ни в одном часовом поясе. Он представляет собой смещение от эпохи. - person OrangeDog; 21.12.2016
comment
@OrangeDog Неверно. Instant наверняка находится в формате UTC. Процитируем документ класса: «Эпоха-секунды отсчитываются от стандартной эпохи Java 1970-01-01T00:00:00Z». Это Z является сокращением от Zulu и означает UTC. Если бы не определение UTC, Instant не имело бы смысла. - person Basil Bourque; 21.12.2016
comment
Тот факт, что представление эпохи в документах находится в Z, не означает, что Instant есть. Чтобы процитировать документ класса: этот Java API определяет свою собственную шкалу времени, Java Time-Scale. - person OrangeDog; 21.12.2016
comment
Мы также можем сказать: Instant арифметически привязан к нулевому смещению UTC (абсолютно необходимо для любого внутреннего расчета даты и времени), но для целей форматирования момент никогда не должен использоваться без часового пояса или смещения для представления локальной информации, и java.time-API предотвращает это, т.е. вынуждает пользователя указывать часовой пояс или смещение при форматировании/анализе момента (в большинстве случаев). - person Meno Hochschild; 21.12.2016