Java: локальное стандартное время для мгновенного - PullRequest
2 голосов
/ 19 июня 2019

Сервис, подобный this , имеет явное примечание, что

Время указано в местном стандартном времени (LST).Добавьте 1 час, чтобы отрегулировать летнее время, где и когда оно наблюдается.

Для объекта LocalDateTime ldt создать момент так же просто, как Instant.of(ldt,zoneId).Однако, если я поставлю ZoneId, то Instant будет предполагать, что корректировка перехода на летнее время (DST) уже произведена, а ldt относится к DST, что не так.Каков наиболее естественный для Java способ заставить конструктор Instant применять «стандартное» смещение, а не учитывать DST?данный год, точные даты переходов DST?Конечно, я могу получить смещение как ZoneOffset offset= ZoneOffset.of(zoneId), а затем вычесть offset.getTotalSeconds() из заданной отметки времени, чтобы перейти к «эталонному» времени.Но присвоение этой скорректированной по эталону метки времени на Instant все еще имеет ту же проблему DST.

РЕДАКТИРОВАТЬ: Как было предложено ниже, я попробовал это:

String str = String.format("%04d-%02d-%02dT%s:00", year, month, day, hourMinutes);
LocalDateTime ldt = LocalDateTime.parse(str);
Instant i1= ldt.toInstant(zoneId.getRules().getOffset(ldt));
Instant key= ldt.toInstant(zoneId.getRules().getStandardOffset(i1));

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

Вы можете получить стандартное смещение ZoneId, позвонив getRules(), а затем getStandardOffset().

Однако вам нужен Instant. Потому что иногда стандартное смещение тоже меняется ...

Таким образом, один из способов - сначала преобразовать LocalDateTime в Instant, используя смещение на LocalDateTime. Затем мы получаем стандартное смещение в этот момент и используем его для получения фактического Instant, которое мы хотим:

LocalDateTime ldt = ...;
Instant i = ldt.toInstant(someZoneId.getRules().getOffset(ldt));
Instant i2 = ldt.toInstant(someZoneId.getRules().getStandardOffset(i));
System.out.println(i2);

I думаю, это не сработает для некоторых конкретных локальных времен, если и стандартное смещение, и смещение DST изменяются одновременно, потому что первый момент i вычисляется со смещением до переход. Вы можете вычислить i со смещением после перехода следующим образом:

Instant i;
ZoneOffsetTransition transition = someZoneId.getRules().getTransition(ldt)
if (transition == null) {
    i = ldt.toInstant(someZoneId.getRules().getOffset(ldt));
} else {
    i = ldt.toInstant(transition.getOffsetAfter());
}
0 голосов
/ 19 июня 2019

Описание ZonedDateTime гласит:

Этот класс обрабатывает преобразование из локальной временной шкалы LocalDateTime в мгновенную временную шкалу Instant.Разница между двумя временными линиями - это смещение от UTC / Гринвич, представленное ZoneOffset.

Преобразование объекта LocalDateTime в ZonedDateTime с atZoneиспользуя идентификатор зоны.

Затем вызовите метод toInstant по умолчанию, который унаследован от класса ChronoZonedDateTime, чтобы получить объект Instant.

...