Время Java в GMT

У меня есть приложение Grails со следующим кодом:

Date now = Calendar.getInstance().getTime() //Also tried new Date()
println "now: " + now

Когда я это делаю, я получаю now: Thu Aug 18 12:47:09 CDT 2011. Мне нужно, чтобы дата была в GMT, а не по местному времени, потому что мне нужно сохранить время GMT в базе данных. Я могу использовать объект simpleDateFormat, чтобы распечатать время в GMT, но мне действительно нужно сохранить его как GMT.

Вопрос: Как преобразовать объект Date в объект Date с использованием GMT?


person Mike Caputo    schedule 18.08.2011    source источник
comment
@jpredham, вероятно, должен получить ответ на этот вопрос, поскольку он прав при получении даты / времени в формате GMT. (Я сам это проверил и убедился, что это правда.) К тому же он новее, а у остальных из нас уже есть неплохая репутация.   -  person Chris Aldrich    schedule 19.08.2011
comment
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Date , java.util.Calendar и java.text.SimpleDateFormat теперь являются устаревшими, замененными java.time классы, встроенные в Java 8 и Java 9. См. Руководство Oracle.   -  person Basil Bourque    schedule 17.02.2018


Ответы (8)


Это подчеркивает, почему Java временами отстой. Все предыдущие сообщения близки, но нам нужно быть очень осторожными, получая текущее время в GMT и текущее время в CDT и вызывая его по Гринвичу.

TimeZone reference = TimeZone.getTimeZone("GMT");
Calendar myCal = Calendar.getInstance(reference);

Это текущее время в формате GMT ​​с контекстом часового пояса GMT.

Чтобы преобразовать в объект Date, который сохраняет зону нетронутой, вам необходимо вызвать:

TimeZone.setDefault(reference);

Этот параметр будет действовать до тех пор, пока ваша текущая JVM. Теперь вызов get Time должен дать желаемый результат.

myCal.getTime();
person jpredham    schedule 18.08.2011
comment
Престижность вам! Я изменил свой пост, чтобы лучше отразить вам сказанное. И даже ZONE_OFFSET не сработала. Хороший улов! - person Chris Aldrich; 18.08.2011

Что ж, если вам действительно нужно время в GMT, вам нужно получить его как GMT (@jpredham прав. Слава вам! Редактирую мой пост, чтобы отразить это)

Итак, сделайте следующее

//this option uses TimeZone
TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
TimeZone.setDefault(gmtTimeZone);
Calendar calendar = Calender.getInstance(gmtTimeZone);

Date myDate = calendar.getTime();
person Chris Aldrich    schedule 18.08.2011

Попробуй это:

println Calendar.getInstance(TimeZone.getTimeZone('GMT')).format('HH:mm:ss')

Обратите внимание, что при преобразовании в дату вы теряете информацию о часовом поясе. Когда Java / Groovy форматирует вашу дату для печати, она автоматически форматирует ее для вашего местного часового пояса. Не волнуйтесь, у вашей даты нет часового пояса, связанного с ней. Вы можете снова добавить правильный часовой пояс, если отобразите его так:

Date now = Calendar.getInstance(TimeZone.getTimeZone('GMT')).time
def formatter = new java.text.SimpleDateFormat('HH:mm:ss')
formatter.timeZone = TimeZone.getTimeZone('GMT')
println formatter.format(now)
person ataylor    schedule 18.08.2011

Внутри объекта Calendar хранится время в формате UTC (современное название GMT). getTimeInMillis() возвращает значение UTC, и, вероятно, это то, что вы хотите сохранить.

person Jim Garrison    schedule 18.08.2011

Вам следует попробовать GregorianCalendar # setTimeZone (TimeZone timeZone).

person SJuan76    schedule 18.08.2011

Использование System.currentTimeMillis () не только намного быстрее, чем использование календаря или даты, оно всегда дает вам время по Гринвичу. Если вы хотите отобразить это время, вы можете использовать SimpleDateFormat, установив часовой пояс, какой хотите.

person Peter Lawrey    schedule 18.08.2011

Вы путаете объект даты и времени с его строковым представлением. Все распространенные библиотеки даты и времени в Java (java.util.Date, Joda-Time, java.time в Java 8) внутренне отслеживают дробное количество секунд с первого момента 1970 года по UTC, игнорируя при этом дополнительные секунды. Итак, во всех трех библиотеках дата и время всегда внутренне в формате UTC / GMT.

Итак, ваш вопрос о том, как преобразовать объект Date в объект Date в GMT (UTC), не имеет смысла.

Две лучшие библиотеки (Joda-Time и java.time) также отслеживают часовой пояс внутри объекта даты и времени. Общеизвестно, что вызывающий беспокойство java.util.Date не имеет назначенного часового пояса, но неправильно применяет текущий часовой пояс JVM по умолчанию, когда вызывается метод toString.

Для справки, Joda-Time быстро с этим справляется.

DateTime nowUtc = DateTime.now( DateTimeZone.UTC );

Вызов метода toString этого объекта создает строку в формате ISO 8601 по зулусскому времени (UTC).

Поищите в StackOverflow «Joda» и «formatter», чтобы найти множество примеров настройки на другие часовые пояса.

person Basil Bourque    schedule 26.05.2014

tl;dr

Instant.now()    // Capture current moment in UTC.
    .toString()  // Generate a String object in standard ISO 8601 format, YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ.

2018-02-16T23:28:01.101324Z

java.time

Современный подход использует классы java.time. Полностью избегайте утомительных устаревших классов даты и времени.

Класс Instant представляет собой момент на шкала времени в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

Сгенерируйте строку в стандартном формате ISO 8601, вызвав toString.

String output = instant.toString() ;

Если вам нужна большая гибкость, чем обеспечивает Instant, например форматирование при генерации строк, используйте OffsetDateTime с константой ZoneOffset.UTC.

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;  // Capture the current moment in UTC.

Для создания строк в нестандартных форматах используйте DateTimeFormatter.


О java.time

java.time фреймворк встроен в Java 8 и новее. Эти классы заменяют неудобные старые устаревшие классы даты и времени, такие как _ 11_, _ 12_, & _ 13_.

Проект 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. Здесь вы можете найти несколько полезных классов, например _14 _, YearWeek, _ 16_ и подробнее.

person Basil Bourque    schedule 16.02.2018