Как я могу получить текущую дату и время в формате UTC или GMT в Java?
Когда я создаю новый Date
объект, он инициализируется текущим временем, но в местном часовом поясе. Как я могу получить текущую дату и время в GMT?
Переведено автоматически
Ответ 1
tl; dr
Instant.now() // Capture the current moment in UTC.
Сгенерируйте строку для представления этого значения:
Instant.now().toString()
2016-09-13T23:30:52.123Z
Подробные сведения
Как указано в правильном ответе Джона Скита, объект java.util.Date не имеет часового пояса†. Но его toString
реализация применяет часовой пояс JVM по умолчанию при генерации строкового представления этого значения даты и времени. Наивного программиста сбивает с толку то, что у даты кажется, что есть часовой пояс, но на самом деле его нет.
Классы java.util.Date
, j.u.Calendar
и java.text.SimpleDateFormat
, поставляемые в комплекте с Java, общеизвестно, что доставляют много хлопот. Избегайте их. Вместо этого используйте любую из этих компетентных библиотек даты и времени:
- java.time. * пакет в Java 8
- Joda-Time
java.time (Java 8)
Java 8 предлагает отличный новый пакет java.time.* для замены старых классов java.util.Date / Calendar.
Получение текущего времени в формате UTC / GMT - это простой однострочный процесс…
Instant instant = Instant.now();
Этот Instant
класс является основным строительным блоком в java.time, представляющим момент на временной шкале в UTC с разрешением наносекунд.
В Java 8 текущий момент фиксируется с разрешением всего до миллисекунд. Java 9 предлагает новую реализацию того, что Clock
фиксирует текущий момент с точностью до полной наносекунды, свойственной этому классу, в зависимости от возможностей аппаратного обеспечения часов вашего хост-компьютера.
Это toString
метод генерирует строковое представление своего значения, используя один конкретный формат ISO 8601. Этот формат выводит ноль, три, шесть или девять цифр (миллисекунды, микросекунды или наносекунды) по мере необходимости для представления доли секунды.
Если вам нужно более гибкое форматирование или другие дополнительные функции, то примените нулевое смещение от UTC для самого UTC (ZoneOffset.UTC
константа), чтобы получить OffsetDateTime
.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
Дамп в консоль…
System.out.println( "now.toString(): " + now );
При запуске…
now.toString(): 2014-01-21T23:42:03.522Z
О java.time
Платформа java.time встроена в Java 8 и более поздних версий. Эти классы заменяют старые, вызывающие беспокойство, устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Чтобы узнать больше, ознакомьтесь с Руководством по Oracle. И найдите в Stack Overflow множество примеров и пояснений. Спецификация - JSR 310.
Проект Joda-Time, который сейчас находится в режиме обслуживания, рекомендует перейти на классы java.time.
Вы можете обмениваться объектами java.time непосредственно со своей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с комплексной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функций java.time перенесена обратно на Java 6 и 7 в ThreeTen-Backport.
- Android
- Более поздние версии Android bundle реализуют классы java.time.
- Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP ....
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и больше.
Joda-Time
ОБНОВЛЕНИЕ: Проект Joda-Time, который сейчас находится в режиме обслуживания, рекомендует перейти на классы java.time.
Используя бесплатную библиотеку с открытым исходным кодом Joda-Time сторонних производителей, вы можете получить текущую дату и время всего одной строкой кода.
Joda-Time вдохновил новые классы java.time.* в Java 8, но имеет другую архитектуру. Вы можете использовать Joda-Time в более старых версиях Java. Joda-Time продолжает работать в Java 8 и продолжает активно поддерживаться (по состоянию на 2014 год). Однако команда Joda-Time рекомендует перейти на java.time.
System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
Более подробный пример кода (Joda-Time 2.3)…
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
Дамп в консоль…
System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );
При запуске…
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
Для получения дополнительных примеров кода, работающего с часовым поясом, смотрите Мой ответ на аналогичный вопрос.
Часовой пояс
Я рекомендую вам всегда указывать часовой пояс, а не неявно полагаться на текущий часовой пояс JVM по умолчанию (который может измениться в любой момент!). Такая зависимость, по-видимому, является распространенной причиной путаницы и ошибок в работе с датой и временем.
При вызове now()
передайте желаемый / ожидаемый часовой пояс, который будет назначен. Используйте DateTimeZone
класс.
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );
Этот класс содержит константу для часового пояса UTC.
DateTime now = DateTime.now( DateTimeZone.UTC );
Если вы действительно хотите использовать текущий часовой пояс JVM по умолчанию, выполните явный вызов, чтобы ваш код был самодокументируемым.
DateTimeZone zoneDefault = DateTimeZone.getDefault();
ISO 8601
Прочитайте о форматах ISO 8601. И java.time, и Joda-Time используют разумные форматы этого стандарта по умолчанию как для синтаксического анализа, так и для генерации строк.
† На самом деле, java.util.У Date есть часовой пояс, скрытый глубоко под слоями исходного кода. Для большинства практических целей этот часовой пояс игнорируется. Итак, для сокращения мы говорим java.util.У даты нет часового пояса. Кроме того, этот скрытый часовой пояс не тот, который используется методом Date toString
; этот метод использует текущий часовой пояс JVM по умолчанию. Тем больше причин избегать этого запутанного класса и придерживаться Joda-Time и java.time.
Ответ 2
java.util.Date
не имеет определенного часового пояса, хотя его значение чаще всего считается связанным с UTC. Почему вы думаете, что оно по местному времени?
Если быть точным: значение в пределах java.util.Date
- это количество миллисекунд, прошедших с эпохи Unix, которая произошла в полночь 1 января 1970 года по Гринвичу. Та же эпоха также может быть описана в других часовых поясах, но традиционное описание дается в терминах UTC. Поскольку с момента фиксированной эпохи прошло несколько миллисекунд, значение в пределах java.util.Date
одинаково по всему миру в любой конкретный момент времени, независимо от местного часового пояса.
Я подозреваю, что проблема в том, что вы отображаете ее через экземпляр Calendar, который использует местный часовой пояс, или, возможно, с помощью Date.toString()
который также использует местный часовой пояс, или SimpleDateFormat
экземпляр, который по умолчанию также использует местный часовой пояс.
Если проблема не в этом, пожалуйста, опубликуйте несколько примеров кода.
Однако я бы все равно рекомендовал вам использовать Joda-Time, который предлагает гораздо более понятный API.
Ответ 3
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
//Local time zone
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
Ответ 4
Это определенно возвращает время UTC: в виде объектов String и Date !
static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static Date getUTCdatetimeAsDate() {
// note: doesn't check for null
return stringDateToDate(getUTCdatetimeAsString());
}
public static String getUTCdatetimeAsString() {
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date stringDateToDate(String StrDate) {
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
try {
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e) {
e.printStackTrace();
}
return dateToReturn;
}