А у вас есть баги на переход к летнему времени?


Сегодня на работе внезапно упал билд — не прошёл один тест на какой-то древней странице админки. Тест был простым и проверял функциональность фильтра по дате. Есть метод который проверяет что между двумя датами есть хотя бы один день. И код примерно такой:

/** Minimal range between dates is one day */
boolean checkMinDatesRange(Date dateFrom, Date dateTo) {
  long millisecondsBetween = dateTo.getTime() - dateFrom.getTime());
  int daysBetween = millisecondsBetween / (1000 * 60 * 60 * 24); // roundinig to int
  return daysBetween >= 1;
}

Как вы уже могли догадаться это воскресенье было последним в марте и перевели стрелки на час вперёд, на летнее время.
В результате millisecondsBetween стало меньше на 36000 миллисекунд и после округления до целого daysBetween стал равен нолю а не ровно один, как ожидал тест.
Отчасти этот код вызван тем что в Java долгое время было просто ужаснейшее Date API и в каждом проекте появлялись свои DateUtils кишащие такими проблемами.

Лечится это через JodaTime или JavaTime примерно так:

int daysBetween = Days.daysBetween(dateFrom, dateTo).getDays()

Тебе ещё не страшно?

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

  • В огромных распределённых базах (как у твитера или фесбука), где вместо удаления\апдейта записи создаётся новая с последним временем может поменяться порядок записей и последняя, правильная запись потеряется. Поэтому в распределёнках используются таймштампы (т.е. абсолютный момент времени без таймзоны) и админы следят за синхронизацией времени на всех серверах.
  • В отчётах круглосуточных онлайн сервисов сумма за день становится больше или меньше чем нервирует тех кто по ним делает проплаты.
  • Один сервер по крону выкладывает данные ночью в три вечера, другой сервер, из другой таймзоны через 15 минут попытается забрать — а из-за перевода там ещё ничего нет.

И такие приколы не только с переводом стрелок, а например с високосным годом, или високосной секундой.
И ладно если вы это ещё кое-как всё написали правильно, но может быть такое что часы не перевились, а то и вовсе батарейка в BIOS села и часы всегда показывают один и тот же день.

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

Например в прошлом году секунда координации вызвала сбои в работе Android, Twitter, Amazon, Netflix и других крупных компаниях где работают весьма толковые программисты.

И это кстати интересная проблема возникает с этой секундой — Земля то, постепенно затормаживается. И потенциально может перестать крутится вообще (т.е. в сутках будет бесконечное число часов), или крутится в обратную сторону (отрицательные часы). Тогда как вообще считать время?

Ну до ладно, это допустим ещё не скоро настанет.
Но уже сейчас есть проблема: релятивистское замедление времени на спутниках. Космонавты когда возвращаются на Землю по сути попадают из прошлого в настоящее. На спутниках всегда учитывается Пространственно-временной континуум — и это ещё поди разберись с ним.

Переводим время на перевод времени

И если с секундой координации никуда не деться, её всё равно куда-то придётся приписывать, то вот переходы на летнее и зимнее время это одно из самых дебильных введений.
Зачем переводить? Официально говорят «ну чтобы энергию беречь». Так а как вы её сбережёте? Всё равно свет будете включать когда потемнеет, а не когда часы скажут. График работы тоже можно корректировать не обращая внимание на время. Всё равно, например рестораны, летом работают дольше.
Фермеры всё равно будут вставать с петухами.
Ну допустим, это удобно что у всех организаций синхронно меняется график.
Но почему тогда перевод стрелок только два раза в год? Летом же солнце всё равно в четыре встаёт, даже с учётом сдвига. Так давайте каждый день переводить стрелки? Чтобы наверняка с первыми лучами все шли на работу. Например в Японии в ответственных случаях работа должна начинаться только через 2 часа после восхода солнца, например, при сдаче экзаменов.

А как быть с теми кто в Заполярье если у них вообще белые ночи и дни? Или тем кто на экваторе, они вообще разницы не заметят.

Ладно, допустим они решили всё равно ввести переход на летнее время. А они вообще подумали как уговорить весь мир перейти тоже?
Вот мы и имеем что в разных странах, да даже в разных областях и провинциях по разному. И разница во времени получается по несколько часов разницы во времени.

Это абсолютный бред и у меня с детских лет кошмарное ощущение что вокруг одни идиоты которые этого не замечают.

Эту дурь придумал какой-то британский мудак которому, видите ли, было обидно в гольф играть в темноте. И вместо того чтобы раньше приезжать он решил что всем нужно под его дудку плясать. Целую жизнь на это положил, не зря прожил, герой.

Как ею могло заразится остальное человечество я не понимаю.
Ещё и исследование какие-то делают на эту тему, кто-то считает количество инсультов, парламентарии спорят, то вводят то отменяют переход. Считают какие-то убытки и экономию.
Это как вообще такое может быть? Что за помешательство?

ИЧСХ все такие прям умные и прогрессивные что-то там якобы считают а по факту потом просто какие-то мудаки у власти принимают решение о переходе просто так, с бухты-барахты.
Сначала во после революции 1917го года матросы начали декреты вводить и выводить. Ну ладно, это была эпоха модерна.
Но блин, уже в наши дни цирк продолжился: «На встрече с молодыми учёными 8 февраля 2011 года президент Медведев объявил о своём решении отменить ежегодный перевод часов, начиная с отмены возврата на «зимнее» время осенью 2011 год. В соответствии с этим решением были подготовлены и приняты Федеральный закон «Об исчислении времени» и постановление правительства. Летнее время осталось в качестве постоянно действующего».
Вот так, царю взбрело в голову и быстренько приняли закон какой надо. Только дебилу было невдомёк что правильное время — это зимнее, а не летнее.
Но кого такие премудрости интересуют, верно?Ввели сразу и бесповоротно, естественно бюрократы не спрашивали у технарей проверили-ли они свои программы и системы. Сколько сбоев и убытков было принесено, а возможно и жизней, никого не интересовало.
Зато опять провели важное исследование и соцопрос где выяснилось что «реформа не нашла поддержки у значительной части населения». Да ну?

Но цирк на этом не закончился, и говно полетело по трубам:
«Вскоре за Россией последовала Белоруссия.
Верховная Рада Украины 20 сентября 2011 года отменила переход на «зимнее» время с целью сохранить летнее время постоянным, однако 18 октября 2011 года отменила своё решение, и перевод часов состоялся в положенное последнее воскресенье октября. (Успели, бараны, отменить за неделю до перевода).
Вслед за первоначальным решением Украины, и мотивируя решение необходимостью жить в одном времени с Украиной, от перевода часов отказалось Приднестровье. Но потом, вслед за Украиной, в Приднестровье перевод часов был продолжен.»

Но и на этом цирк не закончился и в 2014м году в РФ вернулись на постоянное «зимнее» время.

Я это всё наблюдал внимательно каждый раз всё больше и больше офигевая.

Программист помни: время безжалостно к нам

Изучи матчасть, хотя бы эту:

Всегда перед переводом стрелок инспектируй код на предмет возможных пропущенных проблем. Я создал календарь где добавил напоминание на осень перепроверить.
Также было бы очень уместно запустить прогон автоматических регрессионных тестов в сам момент перевода стрелок и после него. Как видите сегодня я именно так и нашёл ошибку.

Знай, что в любой момент эти безумные твари снова захотят отвлечь лохов и поменяют часовой пояс или сделают тебе осеннее время. Или оккупируют тебя, например.
Следи что в твоей системе обновляется tz database и обрати внимание чтобы даты в ОС и БД совпадали, как и на других серверах. Учти что ОСи могут тоже долго не обновлять и тогда нужно делать конфиги или хранить их в БД.

Не верь что всегда будет 24 часа. Не рассчитывай вообще ни на что. Когда нибудь, в Землю обязательно врежется астероид и это изменит траекторию.

И помни, грядёт 2038 год!

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s