ТЛ; др
Instant.ofEpochMilli( 1_317_816_735_000L )
.atZone( ZoneId.of( "Pacific/Auckland" ) )
.format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( new Locale( "en" , "NZ" ) ) )
... тоже ... * * 1004
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
Теперь проанализируйте как LocalDateTime
, поскольку на входе отсутствует какая-либо информация о смещении от UTC или часовом поясе. A LocalDateTime
не имеет понятия смещения или часового пояса, поэтому не представляет фактический момент на временной шкале.
LocalDateTime ldt = LocalDateTime.parse( input );
ZoneOffset
Похоже, вы говорите, что из бизнес-контекста вы знаете, что эта строка предназначена для представления момента, который на 13 часов опережает UTC. Итак, мы создаем ZoneOffset
.
ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.
OffsetDateTime
Примените его, чтобы получить объект OffsetDateTime
. Это становится актуальным моментом на временной шкале.
OffsetDateTime odt = ldt.atOffset( offset);
ZoneId
Но тогда вы упомянули Новую Зеландию. Таким образом, вы имели в виду определенный часовой пояс. Часовой пояс - это смещение от UTC плюс набор правил для обработки аномалий, таких как переход на летнее время (DST). Таким образом, мы можем указать ZoneId
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 ); // Same moment in time, but seen through lens of Paris wall-clock time.
Отсчет с эпохи
Я настоятельно рекомендую не обрабатывать значения даты и времени в виде отсчетов от эпохи, например, миллисекунд с начала 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 по Гринвичу)
2011-10-06T01:12:15+13:00[Pacific/Auckland]
(четверг, 6 октября 2011 г., 01:12:15 в Окленде, Новая Зеландия).
Генерация строк
Чтобы сгенерировать строку в стандартном формате ISO 8601 , просто наберите toString
. Обратите внимание, что ZonedDateTime
разумно расширяет стандартный формат, добавляя название часового пояса в квадратных скобках.
String output = zdt.toString();
Для других форматов выполните поиск переполнения стека для класса DateTimeFormatter
. Уже покрыто много раз.
Укажите FormatStyle
и Locale
.
Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );
Обратите внимание, что часовой пояс не имеет ничего общего с языком 1118 *. У вас может быть Europe/Paris
дата-время, отображаемое на японском языке и культурные нормы, или Asia/Kolkata
дата-время, отображаемое на португальском языке и бразильские культурные нормы.
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют неприятные старые классы даты и времени, такие как java.util.Date
, .Calendar
и & java.text.SimpleDateFormat
.
Проект Joda-Time , который теперь находится в режиме обслуживания , рекомендует перейти на java.time.
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.
Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована к Android в ThreeTenABP (см. Как пользоваться… ).
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.