tl; dr
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
Похоже, вы говорите, что из бизнес-контекста вы знаете, что цель этой строки - представить момент, который на 13 часов опережает UTC. Итак, мы создаем экземпляр ZoneOffset
.
ZoneOffset offset = ZoneOffset.ofHours( 13 );
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 );
Отсчитывать от эпохи
Я настоятельно рекомендую не обрабатывать значения даты и времени как отсчет от эпохи, например миллисекунды с начала 1970 года по Гринвичу. Но если нужно, создайте 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
(Среда, 5 октября 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();
Для других форматов ищите Stack Overflow для 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
отображать дату и время на японском языке и культурных нормах или Asia/Kolkata
дату и время на португальском языке и культурных нормах Бразилии.
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые классы даты и времени , такие как java.util.Date
, .Calendar
, и java.text.SimpleDateFormat
.
Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на java.time.
Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений.
Большая часть функциональных возможностей java.time перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как использовать… ).
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval
, YearWeek
, YearQuarter
и многие другие.