tl; dr
- Не используйте
DateUtil
, что бы это ни было.(Возможно, библиотека Apache DateUtils?) - Не используйте ужасные старые классы даты и времени, такие как
java.util.Date
. - Используйте современные ведущие в отрасли java.time классы.
Код для разбора строки, в которой отсутствует смещение, затем назначение нулевого смещения для самого UTC,
LocalDateTime // Represents a date and a time-of-day but without any concept of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
.parse(
"201801011000" ,
DateTimeFormatter.ofPattern( "uuuuMMddHHmm" )
)
.atOffset( ZoneOffset.UTC ) // Assign an offset-from-UTC. Do this only if you are CERTAIN this offset was originally intended for this input but was unfortunately omitted from the text. Returns an `OffsetDateTime`.
.toInstant() // Extract an `Instant` from the `OffsetDateTime`. Basically the same thing. But `Instant` is always in UTC by definition, so this type is more appropriate if your intention is to work only in UTC. On the other hand, `Instant` is a basic class, and `OffsetDateTime` is more flexible such as various formatting patterns when generating `String` object to represent its value.
Использование java.time
Современный подход в Java использует классы java.time .Эта ведущая в отрасли инфраструктура вытеснила ужасно хлопотные старые классы даты и времени, такие как Date
, Calendar
и SimpleDateFormat
.
DateTimeFormatter
Анализ вашей входной строки.Определите шаблон форматирования для соответствия.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmm" ) ;
String input = "201801011000" ;
LocalDateTime
Выполните синтаксический анализ как LocalDateTime
, поскольку в вашем входе отсутствует индикатор часового пояса или смещения от UTC.
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Отсутствие зоны или смещения означает, что не представляет момент, не - точка на временной шкале.Вместо этого он представляет потенциальных моментов в диапазоне около 26-27 часов, диапазоне часовых поясов по всему земному шару.
OffsetDateTime
Если вы знаете, дляЧтобы убедиться, что эта дата и время дня должны были представлять момент в UTC, примените константу ZoneOffset.UTC
, чтобы получить объект OffsetDateTime
.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
ZonedDateTime
Ваш вопрос расплывчат.Похоже, вы знаете конкретный часовой пояс, предназначенный для этого ввода.Если это так, присвойте ZoneId
, чтобы получить ZonedDateTime
объект.
Поймите, что смещение от UTC - это всего лишь количество часов, минут и секунд.Ни больше ни меньше.В отличие от часового пояса гораздо больше.Часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона.
Укажите правильное имя часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
.Никогда не используйте 3-4-буквенное сокращение, например EST
или IST
, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
Instant
Быстрый способ вернуться обратно в UTC - извлечь объект Instant
.Instant
всегда в UTC.
Instant instan = zdt.toInstant() ;
ISO 8601
Совет: Вместо использования пользовательского формата для обмена значениями даты и времени в виде текста используйте только стандартный ISO8601 форматы.Стандартные форматы практичны, их легко разбирать на машине, их легко читать людям разных культур.
Классы java.time используют форматы ISO 8601 по умолчанию при разборе / генерации строк.Метод ZonedDateTime::toString
разумно расширяет стандарт, добавляя имя зоны в квадратных скобках.
Instant instant = Instant.parse( "2018-07-23T16:18:54Z" ) ; // `Z` on the end means UTC, pronounced “Zulu”.
String output = instant.toString() ; // 2018-07-23T16:18:54Z
И всегда включайте смещение и часовой пояс в вашей строке.Опускать смещение / зону на мгновение - все равно что опускать валюту для цены: все, что у вас осталось, - это неоднозначное число, ничего не стоящее.На самом деле, хуже, чем ничего, поскольку это может вызвать все виды путаницы и ошибок.
О java.time
Java.time framework встроен в Java 8 и новее.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
- Java SE 8 , Java SE 9 , Java SE 10 и позже
- Встроенный.
- Часть стандартного Java API с встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Android
- Более поздние версии комплектов Android для реализации классов java.time .
- Для более ранних версий Android (<26): <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP проект адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .