Управление календарем, датой и временем java для приложения с несколькими часовыми поясами

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

Итак, в качестве примера:
если пользователь находится в часовом поясе EST и смотрит на событие веб-семинара, которое было добавлено другим пользователем в PST, я хочу преобразовать фактическое время PST-события в локальное время для просмотра. Итак, если событие запланировано на 2 дня по тихоокеанскому времени, то оно должно отображаться как 5 вечера EST.

Я также хочу быть осторожным, чтобы производительность не попадала в хит, если есть тысячи событий, для которых может потребоваться преобразование из фактического времени события в локальное время просмотра.

Все мысли и комментарии оценены. ТИА

Ответ 1

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

  • Происходит ли событие в определенный универсальный момент времени? Если это так, вы должны записать время события в формате UTC.

    Например, задача, которая запускается каждые 24 часа, будет назначаться по времени UTC, а не по местному времени. Это может начаться в какую-то местную полночь, но как летнее время изменения вступят в силу, они могут работать в 23:00 или 01:00 локальными часами.

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

    Например, собрание, которое происходит в 08:00 по восточному времени, всегда будет происходить в это местное время. Зимой это будет 13:00 UTC, а летом - в 12:00 UTC.

    Итак, в этом контексте вы не можете записать запланированное время начала с точки зрения UTC. Это очень распространенная ошибка, так как в Интернете есть много советов, в которых говорится, что "всегда хранятся с использованием UTC", что было бы неправильно в этом сценарии.

    Вместо этого вы должны сохранить два значения - местное время, такое как 08:00 и его идентификатор часового пояса IANA, например America/New_York. Вам также может потребоваться сохранить шаблон повторения или определенную дату в зависимости от того, как запланировано событие.

  • Рассмотрите возможность использования Joda Time вместо Java Calendar или Date classess. Это избавит вас от многих головных болей. Убедитесь, что вы прочитали документацию Joda Time и поняли, как это работает.

    Joda Time имеет все функции, необходимые для преобразования между одним часовым поясом и другим, что, по моему мнению, является основной задачей вашего вопроса.

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

  • Также убедитесь, что вы понимаете, что переход от локального времени к конкретному моменту UTC не является идеальной функцией из-за летнего времени. Если событие запланировано в течение недействительного или неоднозначного локального времени, у вас должна быть стратегия для обнаружения и борьбы с этим в вашем приложении. Вы можете просто применить некоторые предположения или, возможно, захотите попросить у пользователя, что делать.

    Например, если я планирую событие в 2:00 по восточному времени каждый день, то 10 марта 2013 года этого времени не существует. Если событие происходит в 3:00? Или это вообще не происходит?

    Другой пример: если я планирую событие в 1:00 по восточному времени каждый день, то 3 ноября 2013 года это время происходит дважды. Должно ли событие происходить в первом (дневном) времени? Или во втором (стандартное время) экземпляре? Или оба? Должен ли я предположить тот или другой, или я должен спросить пользователя, что они имеют в виду?

    Только вы можете решить, что делать, поскольку это ваше приложение. Но игнорирование проблемы, вероятно, приведет к ошибкам.

  • Как только событие прошло, вы можете записать его в UTC, если хотите, или записать его с полным локальным временем и смещением даты. Либо приемлемы. Это прекрасно подходит для исключительных прошлых событий, а не для повторяющихся будущих.