Как сделать, чтобы date.getTime () возвращала время UTC? - PullRequest
19 голосов
/ 08 марта 2010

У меня есть объект Date, который представляет время UTC. Когда я использую метод getTime () для получения длинного значения этого объекта, возвращаемое значение соответствует нашему местному времени (в центральной части США). Как правильно вернуть значение, которое соответствует исходному времени UTC?

Спасибо

Ответы [ 6 ]

22 голосов
/ 09 марта 2010

java.util.Date не имеет понятия о часовом поясе. Это просто время, относящееся к эпохе, то есть 1 января 1970 года 00:00:00 UTC. Дата является моделью, отдельной от представления. При отображении даты применяется понятие часового пояса. Функция toString () для Date отображает удобочитаемую дату в часовом поясе по умолчанию. Вы можете использовать DateFormat для отображения даты в другом часовом поясе (например, в формате UTC) или изменить часовой пояс JVM по умолчанию.

22 голосов
/ 08 марта 2010

В классе DateFormat есть метод для установки предпочтительного часового пояса , а в классе часового пояса есть настройка для времени UTC .

Так, например,

SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);
20 голосов
/ 23 декабря 2016

ТЛ; др

Instant.now()

... и ...

Instant.ofEpochMilli( n ) 

... и ...

instant.toEpochMilli()

Date всегда в UTC

Когда я использую метод getTime () для получения длинного значения этого объекта, возвращаемое значение соответствует нашему местному времени (в центральной части США).

Нет, значение, возвращаемое из Date::getTime(), всегда соответствует UTC (практически то же самое, что и GMT в этом контексте). Чтобы процитировать класс документа:

Возвращает количество миллисекунд с 1 января 1970 г., 00:00:00 по Гринвичу, представленное этим объектом Date.

Так что ваш Вопрос бессмысленен в том смысле, что Date уже в UTC. Нет необходимости «возвращать значение, которое соответствует исходному времени UTC»,

Возможно, вы путаете поведение getTime с поведением toString. Метод toString раздражающе и запутанно применяет текущий часовой пояс по умолчанию в процессе генерации строки. Таким образом, строка выводится с часовым поясом, хотя на самом деле нет часового пояса, который можно установить или получить из самого Date. (На самом деле есть зона глубоко внутри Date, но это не имеет отношения к этому обсуждению здесь. Этот класс - запутанный беспорядок!)

java.time

Современный способ сделать это - использовать классы java.time.

Instant

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

Получить текущий момент.

Instant instant = Instant.now();

Вы можете преобразовать Date в его современную замену, вызвав один из новых методов преобразования, добавленных к старым классам даты и времени. Просто позвоните toInstant, довольно просто.

Instant instant = myJavaUtilDate.toInstant();  

Я вообще не рекомендую использовать номер отсчета эпохи в качестве способа отслеживания времени. Вместо этого придерживайтесь объектов java.time. Вне Java сериализация в текст использует форматы ISO 8601 .

Но, если необходимо, вы можете извлечь количество миллисекунд с 1970-01-01T00: 00: 00Z. Обратите внимание, что это может привести к потере данных! Instant имеет более высокое разрешение наносекунд. Таким образом, переход в миллисекунды может занять долю секунды.

long millisecondsSinceEpoch = instant.toEpochMilli();  // Caution: Possible data-loss in going from nanoseconds to milliseconds.

В другом направлении, от счета до Instant.

Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;

О java.time

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

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

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

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

  • Java SE 8 и SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и SE 7
    • Большая часть функций java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android

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

7 голосов
/ 08 марта 2010

getTime() возвращает «количество миллисекунд с 1 января 1970 года, 00:00:00 по Гринвичу», ни больше, ни меньше (очевидно, вы должны создать его правильно). Вы можете отформатировать его так, как хотите, начиная, например, с конструктор GregorianCalendar(TimeZone).

0 голосов
/ 21 февраля 2018

Большинство функций класса Date устарели, поскольку теперь они смещены в классе Calendar.

Вот код для получения времени UTC из Календаря.

Date date = new Date(timeStamp);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);

Вот пример кода для получения года, месяца и т. Д.

System.out.println(calendar.get(Calendar.YEAR));
System.out.println(calendar.get(Calendar.MONTH));

Календарь также поддерживает много другой полезной информации, такой как, TIME, DAY_OF_MONTH и т.д. Январь 0-го месяца.

0 голосов
/ 12 января 2018
    LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
    Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
    Date formattedDate = Date.from(instant);

    return formattedDate;
...