Подтвердить что ты не робот

Есть ли способ конвертировать 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
4b9b3361

Ответ 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?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с встроенной реализацией ,
    • Java 9 добавляет некоторые мелкие функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport.
  • Android

Проект 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());