Дважды в год в часовых поясах, где переходят на летнее время, с часами происходит нечто странное, что большинство программ никогда не учитывает. Когда часы переводят вперёд, один час местного времени просто не существует, поэтому метка времени вроде «2:30 AM» в эту дату на самом деле никогда не наступала. Когда часы переводят назад, один час проходит дважды, поэтому «1:30 AM» наступает один раз до перевода и один раз после, и голая местная метка времени без дополнительной информации не может сказать, какой из них имеется в виду.
Это не редкий пограничный случай, важный лишь для экзотических сценариев. Это обычное календарное событие, которое повторяется каждый год в каждом поясе с летним временем, и оно незаметно ломает любой код, считающий местное время всегда однозначно определённым. Система планирования, которая хранит «забронировать на 1:45 AM», не сохраняя смещение от UTC на момент бронирования, спустя месяцы не сможет узнать, какой из двух моментов «1:45 AM» имелся в виду, если бронирование приходится на ночь перевода часов.
Самая надёжная практика: хранить метки времени внутри системы везде в UTC и переводить в местное время только для отображения. В UTC нет летнего времени и нет неоднозначности, поэтому момент, зафиксированный таким образом, остаётся верным, что бы потом ни произошло с правилами местного времени. Переводите в местный часовой пояс пользователя только в момент показа, используя действующие правила этого пояса для конкретного момента, и именно поэтому стоит пользоваться определением часового пояса, которое принимает конкретный момент времени, а не только место, вместо того чтобы один раз закешировать смещение и использовать его повторно.
Если вы создаёте что-либо, что планирует или журналирует события, стоит явно протестировать такие пограничные случаи: бронирование на несуществующий час при весеннем переводе часов вперёд, метку времени в повторяющемся часе при осеннем переводе назад и запланированное событие, дата которого пересекает переход между моментом создания и моментом наступления. Ни один из этих случаев не гипотетический. Они происходят по фиксированному, предсказуемому графику каждый год, и один раз протестировать их при разработке гораздо дешевле, чем разбираться с обращением в поддержку о встрече, которая якобы сдвинулась на час.
Если вашей системе нужно правильное смещение для конкретного момента, а не только название пояса, запрашивайте его напрямую, а не выводите из закешированного значения. Определение часового пояса в My Geocode принимает конкретный момент и применяет правила летнего времени для этой даты, поэтому возвращаемое смещение верно даже на самой границе перехода.
Адрес в хорошо картографированном центре города почти ничего не говорит о том, как ваша система справится с сельским маршрутом, спорной границей или запросом вблизи полюсов. Тестируйте сложные случаи намеренно.
Не каждый набор данных с общедоступными на вид сведениями о местоположении можно законно использовать в платном продукте. Реальную границу часто задают условия лицензии, а не техническая доступность.