Поддержка повторяющихся событий в разных часовых поясах и переход на летнее время - PullRequest
0 голосов
/ 02 мая 2018

Встроенная базовая система, которая позволяет пользователю Назначить встречу с человеком A, B, C на определенную дату / время .

Я хотел проверить, что наше решение будет работать при изменениях летнего времени.

Два ключевых класса:

  • User - содержит ZoneId пользователя, т. Е. Europe/Paris, Asia/Tokyo и т. Д.
  • Event - содержит LocalDateTime запланированного события, например. 2018-05-04T10:00:00.000 и ZoneId пользователя на момент создания события, например. Europe/Paris.

Затем мы помещаем событие в наш планировщик:

import org.springframework.scheduling.TaskScheduler;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;

public class MyScheduler {

    private final TaskScheduler executor;

    ...

    public void schedule(Event event) {
        ...
        ZonedDateTime scheduledAt = ZonedDateTime.of(event.getScheduledAt(), event.getScheduledAtTimeZone());
        if (scheduledAt.isAfter(ZonedDateTime.now(ZoneId.systemDefault()))) {
            executor.schedule(task, Date.from(scheduledAt.toInstant()));
        }
    }
}

Если я прав, приведенный выше код должен запустить набор событий на пятницу 10:00 Europe/Paris, независимо от того, установлены ли часы по UTC + 1 или UTC + 2.

Вышеупомянутый подход кажется нормальным?

Я также заметил, что класс ZonedDateTime содержит смещение в дополнение к часовому поясу, например. 2018-05-02T20:46:03.002+01:00[Europe/London]. Единственная причина (я могу придумать), чтобы удерживать смещение, состоит в том, чтобы знать, создал ли пользователь событие при переходе на летнее время или нет.

В этом случае есть ли какая-то польза для нашей системы, хранящей смещение, или у нас только локальное время события и зона, в которой оно было создано?

1 Ответ

0 голосов
/ 03 мая 2018

Единственная реальная проблема, о которой я могу подумать, это угловой случай, когда событие происходит осенью, когда часы перемещаются назад, тогда LocalDateTime может быть неоднозначным, даже зная зону.

Instant обычно рекомендуется для нейтральных точек часового пояса во времени, поэтому, если строго не требуется знать часовой пояс, в котором было создано событие, я бы использовал это. Также, даже если это является требованием, поскольку вы все равно можете оставить ZoneId рядом с ним. Это также сделает ваш код немного проще. Другой нормальный вариант - ZonedDateTime для запланированного времени; мне это меньше нравится.

...