tl; д-р
Instant.ofEpochMilli( 1_317_816_735_000L )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
.format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )
... також ...
LocalDateTime.parse( "2011-10-06 03:35:05".replace( " " , "T" ) )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
java.time
Питання та більшість відповідей використовують застарілі застарілі класи дати та часу з найперших версій Java. Ці старі класи виявилися складними та заплутаними. Уникайте їх. Натомість використовуйте класи java.time.
ISO 8601
Ваш вхідний рядок майже у стандартному форматі ISO 8601. Просто замініть ПРОСТІР посередині на T
.
String input = "2011-10-06 03:35:05".replace( " " , "T" );
LocalDateTime
Тепер проаналізуйте як a, LocalDateTime
оскільки на вході відсутня будь-яка інформація про зсув від UTC або часовий пояс. A LocalDateTime
не має поняття зсуву та часового поясу, тому не відображає фактичний момент на часовій шкалі.
LocalDateTime ldt = LocalDateTime.parse( input );
ZoneOffset
Ви, схоже, хочете сказати, що з ділового контексту ви знаєте, що намір цього рядка - представити момент, який випереджає UTC на 13 годин. Отже, ми створюємо екземпляр a ZoneOffset
.
ZoneOffset offset = ZoneOffset.ofHours( 13 );
OffsetDateTime
Застосуйте його, щоб отримати OffsetDateTime
об’єкт. Це стає актуальним моментом на часовій шкалі.
OffsetDateTime odt = ldt.atOffset( offset);
ZoneId
Але тоді ви згадуєте Нову Зеландію. Отже, ви мали на увазі конкретний часовий пояс. Часовий пояс - це зсув від UTC плюс набір правил для обробки аномалій, таких як літній час. Таким чином, ми можемо вказати ZoneId
a, ZonedDateTime
а не просто зміщення.
Вкажіть правильну назву часового поясу . Ніколи не використовуйте абревіатури з 3-4 букв, такі як EST
або, IST
оскільки вони не є справжніми часовими поясами, не стандартизовані і навіть не унікальні (!). Наприклад, Pacific/Auckland
.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime
Застосувати ZoneId
.
ZonedDateTime zdt = ldt.atZone( z );
Ви можете легко перейти в іншу зону на той самий момент на часовій шкалі.
ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );
Відлік від епохи
Я настійно рекомендую не обробляти значення дати та часу як відлік від епохи, наприклад, мілісекунди від початку 1970 UTC. Але якщо потрібно, створіть Instant
із такого числа.
Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );
Потім, за бажанням, призначте часовий пояс, як показано вище, щоб відійти від UTC.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );
Ваше значення 1_317_816_735_000L
:
2011-10-05T12:12:15Z
(Середа, 05 жовтня 2011, 12:12:15 GMT)
2011-10-06T01:12:15+13:00[Pacific/Auckland]
(Четвер, 6 жовтня 2011, 01:12:15 в Окленді, Нова Зеландія).
Створення рядків
Щоб згенерувати рядок у стандартному форматі ISO 8601 , просто зателефонуйте toString
. Зверніть увагу, що ZonedDateTime
розумно розширює стандартний формат, додаючи назву часового поясу у квадратні дужки.
String output = zdt.toString();
Для інших форматів шукайте DateTimeFormatter
клас переповнення стека . Вже охоплювали багато разів.
Вкажіть a FormatStyle
та a Locale
.
Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );
Зверніть увагу, що часовий пояс не має нічого спільного з мовою. Ви можете вказати Europe/Paris
дату-час японською мовою та культурними нормами, або aAsia/Kolkata
дату-час, відображену португальською мовою та культурними нормами Бразилії.
Про java.time
Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі класи дати і часу , такі як java.util.Date
, .Calendar
, і java.text.SimpleDateFormat
.
Проект Joda-Time , який зараз знаходиться в режимі технічного обслуговування , радить перейти на java.time.
Щоб дізнатись більше, див. Підручник Oracle . І шукайте в Stack Overflow багато прикладів та пояснень.
Значна частина функцій java.time переноситься назад на Java 6 і 7 у ThreeTen-Backport і додатково адаптується до Android у ThreeTenABP (див. Як користуватися… ).
Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є полігоном для можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval
, YearWeek
, YearQuarter
і багато інших.