Есть ли способ конвертировать ZoneId в ZoneOffset в java 8?
У меня есть epoch second и zoneId, методом method1.It может быть преобразован в LocalDateTime с системным значением по умолчанию zoneId, но я не нахожу способ конвертировать epoch second в LocalDateTime методом2, потому что нет ZoneOffset.systemDefault
Я думаю, что это неясно.
import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}
val epochSecond = System.currentTimeMillis() / 1000
LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())//method1
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)//method2
Ответы
Ответ 1
Вот как вы можете получить ZoneOffset
из ZoneId
:
Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);
NB: ZoneId
может иметь различное смещение в зависимости от момента времени и истории конкретного места. Поэтому выбор разных экземпляров приведет к разным смещениям.
Ответ 2
Нет однозначного сопоставления. ZoneId определяет географическую протяженность, в которой с течением времени используется множество разных ZoneOffsets. Если часовой пояс использует летнее время, его ZoneOffset будет отличаться между летом и зимой.
Кроме того, правила летнего времени могут со временем меняться, поэтому ZoneOffset может быть другим, например. 13/10/2015 по сравнению с 13/10/1980.
Таким образом, вы можете найти ZoneOffset для ZoneId для определенного момента времени.
См. также https://en.wikipedia.org/wiki/Tz_database
Ответ 3
ТЛ; др
ZonedDateTime.now(
ZoneId.of( "America/Montreal" )
)
… текущего часового пояса по умолчанию…
ZonedDateTime.now(
ZoneId.systemDefault()
)
Подробнее
Ответ станислава Бшкирцева правильно и прямо отвечает на ваш вопрос.
Но есть и более серьезные проблемы, о чем говорится в Ответе Джона Скита.
LocalDateTime
Я не нахожу способ конвертировать вторую эпоху в LocalDateTime
LocalDateTime
намеренно не имеет понятия о часовом поясе или смещении от UTC. Не вероятно, что вы хотите. Local…
означает любую местность, а не одну конкретную местность. Этот класс не представляет момент, только потенциальные моменты в диапазоне около 26-27 часов (диапазон часовых поясов по всему миру).
Instant
Не нужно начинать с эпохальных секунд, если вы пытаетесь узнать текущее время. Получить текущий Instant
. Класс Instant
представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).
Instant instant = Instant.now();
Внутри этого Instant
находится отсчет наносекунд - эпохи. Но нам все равно.
ZonedDateTime
Если вы хотите увидеть этот момент сквозь призму времени в определенных регионах, примените ZoneId
, чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );
В качестве ярлыка вы можете сделать это непосредственно на ZonedDateTime
.
ZonedDateTime zdt = ZonedDateTime.now( z );
A ZonedDateTime
содержит внутри Instant
. Позвоните в zdt.toInstant()
, чтобы получить тот же момент времени, что и базовое значение в UTC. То же количество наносекунд, начиная с эпохи, в любом случае, как ZonedDateTime
или как Instant
.
Секунды с начала эпохи
Если вам дано количество секунд с начала эпохи, а эпоха - это первый момент 1970 года в UTC (1970-01-01T00:00:00Z
), то передайте это число Instant
.
long secondsSinceEpoch = 1_484_063_246L ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;
![Table of date-time types in Java, both modern and legacy.]()
О java.time
Среда java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Чтобы узнать больше, см. Учебное пособие по Oracle. И поищите в Кару множество примеров и объяснений. Спецификация: JSR 310.
Проект Joda-Time, который теперь находится в режиме обслуживания, рекомендует выполнить переход на классы java.time.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версией. Нет необходимости в строках, нет необходимости в классах java.sql.*
.
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и еще more.
Ответ 4
Как сообщает документация, "это в первую очередь предназначено для конверсий низкого уровня, а не для общего использования приложений".
Переход через Instant
имеет для меня прекрасный смысл - ваша эпоха вторая фактически представляет собой другое представление Instant
, поэтому конвертируйте в Instant
, а затем преобразуйте ее в определенный часовой пояс.
Ответ 5
Я надеюсь, что первые две строки моего решения ниже помогут. Моя проблема заключалась в том, что у меня был LocalDateTime
и имя часового пояса, и мне нужен был instant
, поэтому я мог бы построить java.util.Date
, потому что это то, чего хотел MongoDB. Мой код Scala, но он настолько близок к Java здесь, я думаю, что не должно быть проблем с пониманием этого:
val zid = ZoneId.of(tzName) // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
// 2017-03-16T18:03
val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)
Ответ 6
Следующее возвращает время в миллисекундах для добавления в UTC, чтобы получить стандартное время в этом часовом поясе:
TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()
Ответ 7
Самый простой способ:
ZoneOffset zoneOffsetDefault = ZoneOffset.of(ZoneId.systemDefault().getId());