Дата в LocalDateTime в DateTime с использованием jodatime, но как добавить часовой пояс

Мне все равно, MST это или MDT, но у меня есть объект LocalDateTime со временем (т.е. без часового пояса). Я хочу добавить MST или MDT и создать объект DateTime, чтобы я мог получать миллисекунды, поскольку эпоха для хранения и миллисекунды от эпохи находятся в UTC, конечно, так же, как System.currentTimeMillis в UTC.

Итак, есть ли способ сказать MountainTime независимо от сбережений или летнего времени, поскольку он должен знать, что с даты, которую он имеет сам, правильно? Как это сделать?

спасибо, Дин


person Dean Hiller    schedule 28.11.2012    source источник


Ответы (2)


LocalDateTime - это просто набор чисел (день, месяц, год, час, минута...), которые представляют гражданскую (не физическую) концепцию. Вместо этого Datetime представляет собой физическое понятие (момент времени), которое, кроме того, имеет часовой пояс и, следовательно, может быть выражено в день/месяц/год.

Чтобы преобразовать LocalDateTime в Datetime, вам нужно указать часовой пояс. Однако это преобразование не совсем точно определено; потому что при переходе DST два разных DateTime могут соответствовать одному и тому же LocalDateTime.

person leonbloy    schedule 28.11.2012
comment
так есть ли способ получить DateTime, если у меня есть дата и время, и я знаю, что нахожусь в MountainTime, но я не знаю, является ли время дневным светом или стандартным... Думаю, я мог бы закодировать его в соответствии со спецификацией но старался этого избежать. - person Dean Hiller; 28.11.2012
comment
MountainTime - это часовой пояс? (я не американец) - person leonbloy; 28.11.2012
comment
Есть MST и MDT, которые являются горным стандартным временем и горным летним временем. S и D просто означают смену часов, которая происходит осенью и весной, поскольку это все горное время. - person Dean Hiller; 29.11.2012
comment
Я обнаружил, что мне пришлось промежуточно преобразовать joda LocalDateTime в java.util.Date, а затем в DateTime с указанным часовым поясом. Не уверен, что можно конвертировать напрямую, но мне этого было достаточно. - person cellepo; 04.08.2016
comment
@cellepo: следует напрямую использовать toDateTime - person leonbloy; 04.08.2016

tl;dr

Instant.now()                                      // Capture the current moment in UTC.
       .atZone( ZoneId.of( "America/Edmonton" ) )  // Adjust from UTC to the wall-clock time in use by the people of a particular region (a time zone).

…or…

ZonedDateTime.now( ZoneId.of( "America/Edmonton" ) )

Java.время

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Используйте реальные часовые пояса

Не используйте MST или MDT или другие подобные сокращения из 3-4 букв. Они не соответствуют часовым поясам, не стандартизированы и даже не уникальны(!).

Укажите правильное название часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland.

Если вы имели в виду часовой пояс слева от центра Северной Америки, укажите осмысленный часовой пояс, например America/Edmonton. Помните, что в Аризоне другая зона, так как здесь никогда не применялась чепуха о переходе на летнее время; так что используйте America/Phoenix.

Instant для UTC

Если вы хотите работать в формате UTC, что часто целесообразно, используйте класс Instant. Класс Instant представляет момент на временная шкала в UTC с разрешением наносекунды (до девяти (9) цифр десятичной дроби).

Instant instant = Instant.now();  // Current moment in UTC.

Чтобы сгенерировать строку в стандартном формате ISO 8601, вызовите toString.

String output = instant.toString();

2016-12-06T22:26:32.773Z

Если вы хотите подсчитать полные секунды с эпохи 1970-01-01T00:00:00Z, вызовите getSeconds.

long secondsSinceEpoch = instant.getSeconds();

Для миллисекунд с той же эпохи вызовите toEpochMilli.

long milliseconds = instant.toEpochMilli();

Я настоятельно рекомендую не обрабатывать значения даты и времени как число отсчета от эпохи. Они подвержены ошибкам, их трудно отлаживать, поскольку люди не могут понять значение таких чисел. Вместо:

  • Используйте объекты java.time в своем коде.
  • Используйте строки в формате ISO 8601 при сериализации значений.

ZonedDateTime

Чтобы увидеть тот же момент через призму часового пояса региона, их настенные часы, примените ZoneId, чтобы получить ZonedDateTime.

ZoneId z = ZoneId.of( "America/Edmonton" ;
ZonedDateTime zdt = instance.atZone( z );

Идя в другом направлении, вы можете извлечь Instant для значения UTC.

Instant instant = zdt.toInstant();

LocalDateTime

В вашем вопросе упоминалось наличие LocalDateTime. В классах Local… намеренно отсутствует какая-либо информация о часовом поясе или смещении. Таким образом, они не представляют точку на временной шкале.

LocalDateTime ldt = LocalDateTime.of( 2016 , 1 , 23 , 12 , 34 , 56 );

ldt.toString(): 2016-01-23T12:34:56

Примените часовой пояс, чтобы получить ZonedDateTime, придав этому значению реальный смысл.

ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) );

zdt.toString(): 2016-01-23T12:34:56-05:00[Америка/Монреаль]

Летнее время (DST)

Итак, есть ли способ сказать MountainTime независимо от сбережений или летнего времени, поскольку он должен знать, что с даты, которую он имеет сам, правильно?

Вам не нужно беспокоиться о переходе на летнее время или других подобных аномалиях. Классы java.time обрабатывают это автоматически. Но прочитайте документацию класса, чтобы понять поведение во время перехода на летнее время (прибавка или потеря часа или около того), а также когда вы можете запрашивать время на настенных часах, которого не существует. (за это время часы «прыгают вперед»).


О java.time

java.time встроена в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

Использование драйвера JDBC, совместимого с JDBC 4.2 или более поздней версии вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Нет необходимости ни в строках, ни в классах java.sql.*.

Где получить классы java.time?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. . Этот проект является испытательным полигоном для возможных дополнений к java.time в будущем. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и подробнее.

person Basil Bourque    schedule 07.12.2016