Как сделать date.getTime() возвращает время UTC?
У меня есть объект Date, который представляет время UTC. Когда я использую метод getTime(), чтобы получить длинное значение этого объекта, возвращаемое значение соответствует нашему местному времени (в центре США). Каков правильный способ вернуть значение, соответствующее исходному времени UTC?
Спасибо
Ответы
Ответ 1
Класс DateFormat
имеет метод настройки предпочтительного часового пояса, а также класс часового пояса, который имеет настройка времени UTC.
Итак, например,
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);
Ответ 2
java.util.Date
не имеет понятия о часовом поясе. Он просто проводит время относительно эпохи, которая составляет 1 января 1970 года 00:00:00 UTC. Дата - это модель, отдельная от представления. Когда вы показываете дату, тогда применяется концепция часового пояса. Дата toString() отображает человекочитаемую дату в часовом поясе по умолчанию. Вы можете использовать DateFormat
для отображения даты в другом часовом поясе (например, UTC) или изменить часовой пояс по умолчанию JVM.
Ответ 3
TL;DR
Instant.now()
... и...
Instant.ofEpochMilli( n )
... и...
instant.toEpochMilli()
Date
всегда находится в формате UTC
Когда я использую метод getTime() для получения длинного значения этого объекта, возвращаемое значение соответствует нашему местному времени (в центре США).
Нет, значение, возвращаемое из Date::getTime()
, всегда соответствует UTC (практически в том же смысле, что и GMT GMT). Чтобы процитировать класс doc:
Возвращает количество миллисекунд с 1 января 1970 года, 00:00:00 GMT, представленное этим объектом Date.
Итак, ваш вопрос бессмыслен тем, что a Date
уже в UTC. Нет необходимости "возвращать значение, которое соответствует исходному времени UTC",
Вы можете вводить в заблуждение поведение getTime
с поведением метода toString
. Метод toString
досадно и запутанно применяет текущий часовой пояс по умолчанию в процессе создания String. Таким образом, вывод строки появляется с часовым поясом, в то время как на самом деле не существует часового пояса, который должен быть установлен или получен из самого Date
. (На самом деле есть зона, расположенная глубоко внутри Date
, но это не относится к этой дискуссии здесь. Этот класс - путаница!)
java.time
Современный способ сделать это - использовать классы java.time.
Instant
Instant
класс представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Получить текущий момент.
Instant instant = Instant.now();
Вы можете преобразовать Date
в свою современную замену, вызвав один из новых методов преобразования, добавленных к старым классам времени. Просто позвоните toInstant
, довольно легко.
Instant instant = myJavaUtilDate.toInstant();
Я вообще не рекомендую использовать число count-from-epoch как способ отслеживания времени. Вместо этого используйте файлы 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 и более поздних версий. Эти классы вытесняют неприятные старые 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
, и больше.
Ответ 4
getTime()
возвращает "количество миллисекунд с 1 января 1970 года, 00:00:00 по Гринвичу", ничего больше, не меньше (очевидно, вы должны его правильно создать). Вы можете отформатировать его, как хотите, начиная с, например, конструктор GregorianCalendar(TimeZone)
.
Ответ 5
Kuo написал следующее: "java.util.Date не имеет понятия о часовом поясе". Пожалуйста, объясните это. Также объясните, почему решение Pops не работает.
import java.util.*;
import java.io.*;
import java.text.*;
public class TestClass
{
public void test()
{
long msecs = 13 * 60 * 60 * 1000; // i.e. hour 13
Date date = new Date(msecs);
System.out.println("msecs: " + msecs);
System.out.println("date.getTime(): " + date.getTime());
System.out.println("date.toString: " + date.toString());
SimpleDateFormat fmtr = new SimpleDateFormat("hh:mm:ss");
fmtr.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
System.out.println("fmtr.format(msecs): " + fmtr.format(msecs));
System.out.println("fmtr.format(Date): " + fmtr.format(new java.util.Date(msecs)));
}
public static void main(String[] in_args)
{
TestClass test = new TestClass();
test.test();
}
}
Выход:
msecs: 46800000
date.getTime(): 46800000
date.toString: Thu Jan 01 06:00:00 MST 1970
fmtr.format(msecs): 01:00:00
fmtr.format(Дата): 01:00:00
Ответ 6
LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
Date formattedDate = Date.from(instant);
return formattedDate;