тл; д-р
… Проаналізовано… з рядка… часовий пояс не вказано… Я хочу встановити конкретний часовий пояс
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Немає часової зони в juDate
Як зазначено в інших правильних відповідях, java.util.Date не має часового поясу † . Він представляє UTC / GMT (не зміщено часовий пояс). Дуже заплутаний, оскільки його toString
метод застосовує часовий пояс JVM за замовчуванням під час створення представлення String.
Уникайте juDate
З цієї та багатьох інших причин вам слід уникати використання вбудованого java.util.Date & .Calendar & java.text.SimpleDateFormat. Вони сумно викликають занепокоєння.
Замість цього використовуйте пакет java.time в комплекті з Java 8 .
java.time
Класи java.time можуть представляти момент на шкалі трьома способами:
- UTC (
Instant
)
- З компенсацією (
OffsetDateTime
з ZoneOffset
)
- З часовим поясом (
ZonedDateTime
з ZoneId
)
Instant
У java.time основним будівельним блоком є Instant
момент на часовій лінії в UTC. Використовуйте Instant
об'єкти для більшої частини вашої бізнес-логіки.
Instant instant = Instant.now();
OffsetDateTime
Застосуйте зсув з-за UTC, щоб налаштувати час настінного годинника деяких місцевостей .
Застосуйте, ZoneOffset
щоб отримати OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Краще застосувати часовий пояс , зміщення плюс правила поводження з аномаліями, такими як літній час (DST) .
Застосуйте а ZoneId
, Instant
щоб отримати ZonedDateTime
. Завжди вказуйте належну назву часового поясу . Ніколи не використовуйте 3-4 абревіатури, такі як EST
або IST
які не є ні унікальними, ні стандартизованими.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Якщо у вхідному рядку не було жодного індикатора зміщення чи зони, проаналізуйте як a LocalDateTime
.
Якщо вам відомо про запланований часовий пояс, призначте команду ZoneId
a ZonedDateTime
. Дивіться приклад коду вище в розділі tl; dr вгорі.
Форматизовані рядки
Викличте toString
метод у будь-якому з цих трьох класів для створення рядка, що представляє значення дати та часу у стандартному форматі ISO 8601 . ZonedDateTime
Клас розширює стандартний формат шляхом додавання імені тимчасової зони в дужках.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
Для інших форматів використовуйте DateTimeFormatter
клас. Як правило, краще, щоб цей клас генерував локалізовані формати, використовуючи очікувані користувачем людські мовні та культурні норми. Або ви можете вказати певний формат.
Про 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
, і більш .
Joda-Time
Поки Joda-Time все ще активно підтримується, його виробники сказали нам перейти на java.time, як тільки зручно. Цей розділ я залишаю недоторканим як посилання, але пропоную використовувати java.time
розділ вище.
У Joda-Time об’єкт дати ( DateTime
) дійсно знає призначений часовий пояс. Це означає зміщення від UTC та правил та історії літнього часу (DST) цього часового поясу та інших подібних аномалій.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Викличте toString
метод для створення рядка у форматі ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time також пропонує багаті можливості для генерації всіх видів інших форматів String.
Якщо потрібно, ви можете конвертувати з Joda-Time DateTime в java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Шукайте в StackOverflow "дату joda", щоб знайти ще багато прикладів, деякі досить детальні.
† Насправді є часовий пояс, вбудований у java.util.Date, який використовується для деяких внутрішніх функцій (див. Коментарі до цього відповіді). Але цей внутрішній часовий пояс не виставляється як властивість і його не можна встановити. Цей внутрішній часовий пояс не є тим, який використовується toString
методом для формування рядкового подання значення дати та часу; натомість застосовується поточний часовий пояс JVM за замовчуванням. Отже, як скорочено, ми часто кажемо, що "juDate не має часового поясу". Заплутано? Так. Ще одна причина уникати цих втомлених старих занять.