tl; dr
Ваша первоначальная проблема была опечаткой +1000
против +0100
.Тем не менее, все советы, приведенные ниже, остаются в силе.Вы используете ужасные старые классы, которых следует избегать.
OffsetDateTime.parse(
"2018-12-04T22:22:01+1000" , // Input in standard ISO 8601, with the COLON omitted from the offset as allowed by the standard but breaking some libraries such as `OffsetDateTime.parse`.
DateTimeFormatter.ofPattern(
"uuuu-MM-dd'T'HH:mm:ssX"
)
) // Returns a `OffsetDateTime` object.
.toInstant() // Adjust into UTC. Returns an `Instant` object. Same moment, different wall-clock time.
.atZone( // Adjust from UTC to some time zone. Same moment, different wall-clock time.
ZoneId.of( "Europe/Brussels" )
) // Returns a `ZonedDateTime` object.
.toString() // Generate text representing this `ZonedDateTime` object in standard ISO 8601 format but wisely extending the standard by appending the name of the time zone in square brackets.
18-12-04T13: 22: 01 + 01: 00 [Европа / Брюссель]
Избегайте устаревших классов даты и времени
Вы используете ужасные старые классы даты и времени, связанные с ранними версиями Java.Шестнадцать лет тому назад классы java.time .
Использовали надлежащие часовые пояса
FYI, CET
не является реальным часовым поясом.
Укажите собственное имя часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
.Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
Вы, вероятно, имеете в виду часовой пояс, например Europe/Brussels
, Europe/Paris
, Europe/Berlin
, Africa/Tunis
или Europe/Oslo
.
ISO 8601
Ваша строка ввода 2018-12-04T22:22:01+1000
в стандартном формате, определенном ISO 8601 .
Последняя часть +1000
представляет собой смещение от UTC , что означает момент на десять часов раньше UTC.Таким образом, это значение предназначалось для настенного времени, используемого людьми в каком-либо регионе Тихого океана, например, в часовом поясе Australia/Lindeman
.
Не сокращать обозначение смещения
Эта строка +1000
является сокращением смещения, опуская разделитель символов COLON между часами и минутами (и секундами, если они есть).Хотя стандарт допускает это упущение, я предлагаю всегда включать COLON: 2018-12-04T22:22:01+10:00
.По моему опыту, некоторые библиотеки и протоколы ломаются при обнаружении таких строк.А включение COLON делает строку более читабельной для людей.
OffsetDateTime
Действительно, класс java.time.OffsetDateTime
, предназначенный для анализа таких стандартных строк по умолчанию, имеет ошибку в этом отношении.разобрать, когда COLON опущен.Обсуждено по адресу:
Обходной путь:
OffsetDateTime odt =
OffsetDateTime.parse(
"2018-12-04T22:22:01+1000" ,
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ssX" )
)
;
См. Пример кода runninglive at IdeOne.com .
odt.toString (): 2018-12-04T22: 22: 01 + 10: 00
Настройте это значение вUTC путем извлечения объекта Instant
.Instant
всегда в UTC по определению.
Instant instant = odt.toString() ;
instant.toString (): 2018-12-04T12: 22: 01Z
Наконец, мы можемнастроить в свой собственный приходской часовой пояс.
Под CET
Я предполагаю, что вы имели в виду часовой пояс, например Europe/Paris
.
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
При вызове ZonedDateTime::toString
текст генерируется в стандартном формате ISO 8601, но разумно расширяетсястандарт для добавления имени часового пояса в квадратных скобках.
zdt.toString(): 2018-12-04T13:22:01+01:00[Europe/Paris]
Все три из эти объекты (odt
, instant
, & zdt
) относятся к одному и тому же одновременномумомент , та же самая точка на временной шкале.Их единственное отличие - время настенных часов.Если бы три человека на телефонной конференции в Австралии, Франции и Исландии (всегда в UTC) одновременно смотрели вверх, чтобы прочитать текущий момент с их соответствующих часов, висящих на их локальной стене, они прочитали бы три разных значения для одного и того же одновременного момента.
Просмотреть весь этот код запустить на этой странице IdeOne.com .
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Руководство по Oracle .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .