Рано или поздно, любой программист столкнётся с часовыми поясами.
И я тут особо ничего не могу посоветовать; могу только рассказать одну поучительную историю.
Я вам расскажу почему лучше никогда, никогда не работать с часовыми поясами если этого можно избежать.
Представим, что кто-то разработал приложение,
которое позволяет посчитать, сколько прошло секунд с такого-то события в прошлом.
Мы вводим дату и время, и оно выдаёт количество секунд.
Он смотрит на результат и думает: "Так, вроде бы как работает..."
"Но добавим-ка небольшое меню, в котором можно выбрать часовой пояс!"
Так что если, например, нужно посчитать время между сейчас в Нью-Йорке и 5 днями назад в Лондоне -- можно решить эту проблему.
И отлично: небольшое меню позволяет выбрать, на сколько часов вперёд или назад мы находимся от Гринвича.
Потрясающе.
Рано или поздно, когда приложение наберёт популярность, программисту позвонят из Австралии.
И Австралия скажет "Здаров-"
Не, лучше без акцентов.
Я просто не должен делать акценты.
И Австралия скажет: "Здравствуйте!"
"Кстати, у нас тут 9 с половиной часов разницы с Гринвичем"
И программист такой "неужели?"
"Ага, 9½ часов."
"Окей, добавляю ради вас особый пояс. Хорошо."
Немного позднее, ему позвонят из Непала.
И они скажут: "Здравствуйте. А у нас 5 с четвертью часов разницы с Гринвичем."
И он отвечает: "да ладно?" -- "Ну да, испокон веков так было! Ровно 5¼ часов!"
Отлично. Ладно. И он внесёт ещё один особый пояс. Может быть он даже поищет
список часовых поясов. Канонический список, в котором указано,
где какой пояс, и он удостоверится, что он покрыл все возможные часовые пояса в мире.
И вот приходит осень.
Ему звонят из Англии.
Англия говорит: "Прошу прощения. У нас тут расхождение в один час, что происходит?"
И он такой: "Погоди-ка, только что же стрелки перевели!"
"Ну да... но я же учёл это!"
"Я узнал когда у нас переводят часы на зимнее время, и я это внёс в приложение!"
А Англия говорит: "Нет, видите ли, у нас зимнее время наступает на неделю раньше."
"В разных местах по-разному."
"Мы переводим стрелки на неделю раньше вас."
И в этот момент,
в этот момент программист обычно начинает обхватывать свою голову руками,
осознавая во что же он ввязался.
И хорошо! Он исправляет приложение,
он разбирается с каждой страной, где и когда начинается зимнее время.
Он находит файл в котором всё это перечислено, копирует, и дело сделано.
Затем ему звонят откуда-то из южного полушария и говорят:
"Вообще-то мы сейчас переводим не назад, а вперёд."
"У нас весна... в ноябре."
В этот момент он обычно начинает смотреть жаждуще на свой любимый хмельной напиток
и думать, стоит ли ему немного принять перед тем как идти дальше,
но в конце концов он это тоже исправит.
Затем ему звонят из Самоа --
откуда-то из Тихого Океана, с линии перемены даты.
И Самоа говорит: "Здравствуйте!"
"Мы тут недавно день пропустили."
Программист отвечает: "как так?"
"Да, пропустили день. Мы перескочили от 29 декабря 2011 года сразу к 31 декабря."
"Теперь мы по другую сторону линии перемены даты. Раньше были на кучу часов позади Гринвича,"
"а теперь мы на кучу часов впереди Гринвича. Так легче торговать с Австралией."
"Вы можете это учесть, когда будете считать сколько прошло дней, сколько секунд с такого-то события?"
...ну хорошо, у нас есть файл, в котором говорится какая страна когда сменила часовой пояс.
Оказывается, что такое происходит довольно часто.
Но подобные смены объявляются заблаговременно, так что пока мы вовремя обновляем этот файл
и вносим соответствующий код в приложение, проблем не будет.
Затем мы замечаем, что во время Второй мировой войны
Англия жила по двойному летнему времени.
Сначала они полностью перешли на летнее время, а затем просто добавили ещё один час.
Так что они были на два часа впереди Гринвича, даже в самом Гринвиче.
Ну ладно, это мы тоже учтём.
Заметили, я начал говорить будто это у нас проблемы?
Потому что я с этим уже сталкивался, и это было очень, очень напряжно.
Ты удостоверяешься, что подписался на список
того когда страны изменят их часовые пояса -- что происходит, оказывается, постоянно!
Иногда по нескольку раз за год, из-за частой смены правительств.
И тогда наш программист, мифический программист получает звонок из Ливии.
Они в 2013 году, всего за пару дней до перевода часов, решили никуда стрелки не переводить.
С таким поздним уведомлением никому не было возможно обновить список вовремя.
Поэтому все компьютеры в Ливии, не важно на какой операционной системе они работали,
опаздывали на час.
Ну и ладно, ты читаешь новостную статью об этом и в спешке исправляешь код.
И затем ты получаешь звонок c Западного берега Иордана.
Где израильское население живёт по времени отличающемся от палестинского населения.
Потому что одни признают Израиль, а другие нет.
Так что теперь у есть нас две группы людей на одной территории, следующие разным часовым поясам.
И им приходится спрашивать себя, в этом они часовом поясе или в том, в зависимости от того кто они и где они,
и это никак невозможно запрограммировать. И затем,
затем тебе звонит историк.
Он говорит: "Так, я пытаюсь рассчитать времена с событий в 18 веке."
"И мы перешли с юлианского календаря на григорианский календарь."
"Не то что бы мы потеряли где-то три недели,"
"просто мы перескочили вот с этой даты к той дате, и пропустили остальные."
"Не могли бы вы это запрограммировать, чтобы это как бы учлось у меня?"
Ну и ладно, ведь кто-то уже сказал тебе что это за даты,
и ты можешь также внести их в логику программы,
но теперь этот код выглядит чересчур длинным и очень запутанным,
запутанная куча спагетти-кода которая каким-то чудом работает,
и затем тебе звонит русский историк!
Он говорит: "Да, мы перешли на григорианский календарь лишь 20 веке!"
(оказывается, даты, которые мы пропускаем, меняются в зависимости от локации)
"...можете это тоже учесть?.." И затем тебе звонит британский историк!
Он говорит что вплоть до, думаю, 16 века,
год начинался 25 марта!
Просто взрыв мозга.
Вот 24 марта 924 года,
и затем идёт 25 марта 925 года -- и это следующий день.
Потому что после 31 декабря 924 идёт 1 января 924 -- потому что такой порядок!
Всё это невероятно запутано, И ЗАТЕМ...
Тебе звонит астрофизик!
Он говорит: "Кстати говоря, только что прошла високосная секунда"
И в этот момент, ты такой "ЧТО."
Високосная секунда. Потому что Земля вращается с непостоянной скоростью.
Она замедляется, она ускоряется: из-за движения тектонических плит,
из-за сдвигов магнитных полей, или чего-то в этом роде. Так что время от времени
Международный астрономический союз решает, нужна ли нам високосная секунда.
Если нужна, то часы идут 23:59:58,
затем 23:59:59,
и затем, вместо того чтобы идти... как все нормальные часы,
они идут 23:59:60!
И всё рушится потому что ни стого ни с сего у нас 61 секунда в минуте!
Так что в зависимости от нашей имплементации, либо
наши часы идут с ошибкой в одну секунду с остальным миром,
либо повторяют одну секунду.
С этим лучше всего справляться с помощью системы под названием UNIX-время.
Канал Numberphile, вроде, это уже обсуждал.
Когда у нас есть число, начавшее отсчёт ровно в первую секунду 1970 года
и увеличивающееся на одну секунду каждую секунду.
Постоянно. Тик. Тик. Тик.
И отлично, ведь теперь всё что нам остаётся, это взять любую нужную дату,
пересчитать её в терминах UNIX-времени,
и записать в нашу базу данных.
И этот подход учтёт високосные секунды,
ДА НИЧЕГО НЕ УЧТЁТ! Конечно не учтёт!
Потому что у нас есть Всемирное координированное время (UTC),
которое включает в себя високосные секунды:
оно повторяется время от времени, показывает 23:59:60.
А ещё у нас есть астрономическое время! В него високосные секунды не включены,
и оно постоянно увеличивает своё расхождение с остальным миром,
потому что нам нужно смотреть на звёзды и разрабатывать телекопы исходя из этого.
И ты поймёшь...
Ты поймёшь, поработав вдоволь с часовыми поясами, что лучше поступить так:
ты откладывешь свой код в сторону
и даже не пытаешься работать с поясами самостоятельно.
Ты смотришь на тех, кто с этим всем сталкивался до тебя.
Ты смотришь на тех первых, кто прошёл через всё это.
На тех, кто написал этот спагетти-код,
ты идёшь к ним, благодаришь их от всей души за то, что их код в открытом доступе,
отдаёшь им должное, берёшь то, что они написали, вставляешь в свою программу,
и навсегда забываешь о его существовании.
Потому там царит безумие.
В Google кстати применили очень, очень хороший подход к високосным секундам, который они сами и придумали.
В их блоге есть статья об этом, я думаю, там всё объясняется.
Они это называют "високосное размазывание" [leap smear]
Потому что иметь 61 секунду в минуте,
или иметь часы идущие назад на секунду,
может быть очень, очень плохо для огромных корпораций
которым необходимо скрупулёзно всё синхронизировать и точно знать какая часть информации была записана раньше другой.
Так что они просто размазывают секунду на протяжении целых суток,
добавляют ко времени по одной микросекунде за раз.
Тик-тик-тик-тик-тик, и так целые сутки.
Так что может они иногда и расходятся на полсекунды с остальным миром,
зато все их сервера расходятся на полсекунды одновременно.
Так что их время расходится с остальным миром, но зато они точно знают что и когда произошло.
Обладать непрерывным временем намного важнее, чем, собственно, знать точное время.