ТЛ; др
java.time.Instant.ofEpochMilli( 1_554_091_200_000L )
Всегда указывайте часовой пояс
Вы узнали, что классы даты и времени прибегают к неявному применению текущего часового пояса JVM по умолчанию, если вы не указали его. Это означает, что ваши результаты могут отличаться во время выполнения. Хуже того, ваши результаты могут отличаться во время выполнения , поскольку любой код в любом потоке любого приложения в JVM может изменить значение по умолчанию !
Лучше всегда указывать желаемый / ожидаемый часовой пояс. И если это важно для вашего приложения, подтвердите зону с пользователем.
Еще лучше: сосредоточиться на работе в UTC. Используйте часовой пояс только там, где этого требует бизнес-логика или для представления пользователю.
ZoneId
Укажите собственное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Если вы хотите использовать текущий часовой пояс JVM по умолчанию, запросите его и передайте в качестве аргумента. Если опущен, код становится неоднозначным для чтения, поскольку мы точно не знаем, намеревались ли вы использовать значение по умолчанию или если вы, как и многие программисты, не знали об этой проблеме.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Joda-Time
Вы должны знать, что отличный проект Joda-Time сейчас находится в режиме обслуживания. Его создатель, Стивен Колебурн, использовал полученные там уроки, чтобы найти JSR 310 и его реализацию, классы java.time .
См. Маркеры ниже для более старых Android и Java.
Класс java.time.Instant
представляет момент в UTC. Внутренне это число наносекунд с первого момента 1970 года в UTC.
Instant instant = Instant.ofEpochMilli( 1_554_091_200_000L ) ;
ZoneId z = ZoneId.of( "America/Puerto_Rico" ) ;
ZonedDateTime zdt = instant.atZone( z )
Instant
и ZonedDateTime
представляют один и тот же момент, одну и ту же точку на временной шкале. Тот же самый момент одновременно отображается по-разному, что видно по настенным часам, используемым людьми определенного региона (часового пояса).
См. Этот код, запущенный в режиме реального времени на IdeOne.com .
instant.toString (): 2019-04-01T04: 00: 00Z
zdt.toString (): 2019-04-01T00: 00-04: 00 [America / Puerto_Rico]
Clock
Для лучшего тестирования передайте альтернативные Clock
объекты в качестве необязательного аргумента различным методам. См. Класс Clock
, чтобы получить часы, которые застряли в определенный момент , или которые отстают от истинного времени , или используют другую частоту , такую как увеличиваясь со скоростью целых секунд или целых минут .
Переполнение стека поиска
Переполнение стека поиска. Все эти темы уже были рассмотрены много раз.
Совет: используйте поисковую систему в Интернете, такую как DuckDuckGo, с критерием site:stackoverflow.com
. Средство поиска в переполнении стека является анемичным, неисправным и смещенным в сторону просмотра вопросов, а не ответов.
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?