Получить время по Гринвичу в Java
В Java я хочу получить текущее время в GMT.
Я пробовал различные варианты:
Date date = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
date1 = calendar.getTime();
Но дата всегда интерпретируется в моем локальном часовом поясе.
Что я делаю неправильно и как я могу преобразовать дату Java в GMT?
Ответы
Ответ 1
Скорее всего, вы сделали правильные вещи на заднем конце, чтобы получить дату, но нет ничего, что указывало бы, что вы не принимали это время по Гринвичу и отформатировали его в соответствии с текущим языковым стандартом вашего компьютера.
final Date currentTime = new Date();
final SimpleDateFormat sdf =
new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
// Give it to me in GMT time.
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + sdf.format(currentTime));
Ключ должен использовать ваш собственный DateFormat, а не систему. Таким образом вы можете установить часовой пояс DateFormat в соответствии с тем, что хотите, вместо того, чтобы быть установленным в Часовой пояс Locale.
Ответ 2
Интересно, почему никто не делает это
Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));
Date date = time.getTime();
Обновление: начиная с Java 8,9,10 и более, должны быть лучшие альтернативы, поддерживаемые Java. Спасибо за ваш комментарий @humanity
Ответ 3
По моему опыту, связанные классы Calendar и Date в Java могут давать эффект нижнего уровня.
Если вы не возражаете перейти на Java 8, рассмотрите возможность использования ZonedDateTime
так:
ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );
Ответ 4
TL;DR
Instant.now()
java.time
Ответ Damilola является правильным, предлагая использовать фреймворк java.time, встроенный в Java 8 и более поздние версии. Но этот ответ использует класс ZonedDateTime
, который является излишним, если вы просто хотите UTC, а не какой-либо конкретный часовой пояс.
Неудобные старые классы даты и времени теперь устаревают, вытесняются классами java.time.
Instant
Instant
класс представляет момент на временной шкале в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).
Простой код:
Instant instant = Instant.now() ;
instant.toString(): 2016-11-29T23: 18: 14.604Z
Вы можете представить Instant
как строительный блок, к которому вы можете добавить часовой пояс (ZoneID
), чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
О java.time
Структура java.time встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь режим обслуживания, советует перейти на java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация JSR 310.
Где получить классы java.time?
- Java SE 8 и SE 9 и позже
- Встроенный.
- Часть стандартного Java API с объединенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Android
Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
Ответ 5
Чтобы получить время в миллисе в GMT, вам нужно всего
long millis = System.currentTimeMillis();
Вы также можете сделать
long millis = new Date().getTime();
и
long millis =
Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis();
но это неэффективные способы совершения одного и того же вызова.
Ответ 6
Попробовав множество методов, я узнал, что для получения времени в миллисе в GMT вам нужно создать два отдельных объекта SimpleDateFormat
, один для форматирования в GMT и еще один для синтаксического анализа.
Вот код:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = new Date();
SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateTime= dateParser.parse(format.format(date));
long gmtMilliSeconds = dateTime.getTime();
Это прекрасно работает.:)
Ответ 7
Это довольно просто и прямо.
Date date = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
date = cal.getTime();
Теперь дата будет содержать текущее время по Гринвичу.
Ответ 8
Полезные методы Утилиты, как показано ниже, для управления временем в GMT с DST Экономия:
public static Date convertToGmt(Date date) {
TimeZone tz = TimeZone.getDefault();
Date ret = new Date(date.getTime() - tz.getRawOffset());
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if (tz.inDaylightTime(ret)) {
Date dstDate = new Date(ret.getTime() - tz.getDSTSavings());
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if (tz.inDaylightTime(dstDate)) {
ret = dstDate;
}
}
return ret;
}
public static Date convertFromGmt(Date date) {
TimeZone tz = TimeZone.getDefault();
Date ret = new Date(date.getTime() + tz.getRawOffset());
// if we are now in DST, back off by the delta. Note that we are checking the GMT date, this is the KEY.
if (tz.inDaylightTime(ret)) {
Date dstDate = new Date(ret.getTime() + tz.getDSTSavings());
// check to make sure we have not crossed back into standard time
// this happens when we are on the cusp of DST (7pm the day before the change for PDT)
if (tz.inDaylightTime(dstDate)) {
ret = dstDate;
}
}
return ret;
}
Ответ 9
Предположим, только внешнее представление представляет интерес. Следующее сработало для меня без лишних слов. Он основан на объекте java.util.Calendar и на java.util.Formatter.
Кажется, что объект календаря действует как объект даты с изменяющимся часовым поясом вместо часового пояса по умолчанию и принимается средством форматирования вместо даты.
Тестовый код был:
Calendar cl = Calendar.getInstance();
cl.setTimeInMillis(System.currentTimeMillis());
System.out.println("cl="+String.format(
"%1$ta, %1$td %1$tb %1$tY %1$tT %1$tZ", cl));
cl.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("cl="+String.format(Locale.ENGLISH,
"%1$ta, %1$td %1$tb %1$tY %1$tT %1$tZ", cl));
Результат был:
cl=Mi, 06 Feb 2019 13:51:41 MEZ
cl=Wed, 06 Feb 2019 12:51:41 GMT
Ответ 10
После Java 8 вы можете получить отформатированное время, как показано ниже:
DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));
Ответ 11
Вы не можете
Во-первых, вы спрашиваете о невозможном. Старомодный объект Date
не получил, так как не может иметь часовой пояс или смещение по Гринвичу.
Но дата всегда интерпретируется в моем местном часовом поясе.
Я предполагаю, что вы напечатали Date
или сделали что-то еще, что неявно вызывает его метод toString
. Я считаю, что это единственный раз, когда Date
интерпретируется в вашем часовом поясе. Точнее в текущем часовом поясе по умолчанию вашей JVM. С другой стороны, это неизбежно. Date.toString()
ведет себя таким образом, он выбирает параметр часового пояса JVM и использует его для визуализации возвращаемой строки.
Вы можете с java.time
Вы не должны использовать Date
, хотя. Этот класс плохо спроектирован и, к счастью, давно устарел. Также java.time, современный Java-API даты и времени, который заменяет его, имеет один или два класса для даты и времени со смещением от GMT или UTC. Я считаю GMT и UTC синонимами, строго говоря, это не так.
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println("Time now in UTC (GMT) is " + now);
Когда я только что запустил этот фрагмент, результат был:
Время в UTC (GMT): 2019-06-17T11: 51: 38.246188Z
Трейлинг Z
выхода означает UTC.
связи