Заблуждения программистов о времени

в 13:03, , рубрики: Без рубрики
Заблуждения программистов о времени - 1
Музей-скансен эпохи Средневековья в Дании в режиме обычной работы (слева) ставит целью воссоздать повседневную жизнь города на стыке XIV и XV веков. Для съёмок фильма (справа) он «погрязнел»

Для киносъёмок в музей под открытым небом Middelaldercentret внесли несколько изменений. Вместо аккуратной каменной улицы развели неприятную кашицу из грязи, не самые роскошные стеклянные окна прикрыли досками и развесили везде выцветшее тряпьё. Здания как следует измазали чем-то коричневым, кое-где зачем-то перемешав субстанцию с соломой. В случайное здание воткнули факел, а не попытались изобразить лучину или фонарь.

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

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

Попытки собрать заблуждения про время и часовые пояса на Хабре уже были шесть и десять лет назад. Но без контрпримеров не так интересно.

Заблуждение 1. В сутках 24 часа или 86 400 секунд

Иногда и кое-где стрелки часов переводят, создавая сутки длиной в 23 и 25 часов — всё очевидно. Будет неплохо углубиться в случаи поэкзотичней.

Наша планета совершает полный оборот вокруг своей оси за примерно 23 часа 56 минут 4 секунды (звёздные сутки, относительно удалённых звёзд) или за 24 часа, если выбирать в качестве точки отсчёта центр Солнца. Разница в 3 минуты 56 секунд случается потому, что Земля совершает полный оборот вокруг Солнца за то время, что ей нужно совершить около 366,25 оборотов вокруг своей оси.

Скорость вращения варьируется день ото дня: влияют циклы приливов и отливов и вообще гравитационное воздействие Луны, изменения погоды и климата, передвижения материи на поверхности Земли и в её ядре. За сутки набегают доли миллисекунды разницы. К примеру, самый короткий день 2022 года — 29 июня, когда сутки продлились на 1,59 миллисекунды меньше, самый длинный — 5 ноября, когда у Земли ушло на свой оборот на 1,01 миллисекунды больше обычных 24 часов.

Международная служба вращения Земли отслеживает по вращению нашей планеты всемирное универсальное время UT1, которое постепенно уходит от UTC (Coordinated Universal Time, всемирное координированное время). Живём нашу повседневную жизнь мы по UTC, нисколько не задумываясь о вопросах астрономической важности. Но если разница между UTC и UT1 составляет больше 0,9 с, принимается решение о введении високосной секунды. Такое случается примерно раз в полтора года.

Заблуждения программистов о времени - 2
Високосные секунды с 1972 года

Високосные секунды добавляют обычно 30 июня или 31 декабря, в последние дни этих месяцев. В этом случае в полночь на секунду появляется необычная комбинация 23:59:60.

Совсем недавно, 18 ноября, дополнительные секунды решили отменить. Новых високосных секунд не будет уже после 2035 года. Делегаты от России просили сдвинуть дату на 2040 год или позднее, чтобы успеть разобраться со спутниками и наземными станциями ГЛОНАСС. Дело в том, что ГЛОНАСС високосные секунды поддерживает. Представители Канады, США и Франции напротив предлагали отказаться раньше 2035 года — в GPS и многих других системах високосные секунды игнорируются.

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

Заблуждения программистов о времени - 3
График нагрузки на один из пострадавших серверов в 2012 году, блог компании Anchor

Десятилетие назад високосная секунда массово заставляла падать серверы на Linux: демон ntpd запускал вызов adjtimex(2) с запросом для ядра вставить високосную секунду, что приводило к лайвлоку. Повышенное энергопотребление из-за 100-процентной нагрузки на процессор отмечали многие хостинг-компании. Шесть лет назад високосная секунда вызвала сбой в DNS у Cloudflare.

Заблуждение 2. Високосные секунды больше не важны. История не играет роли

Високосные секунды когда-то отменят в будущем, но они точно останутся в прошлом. Это значит, что их всегда придётся учитывать в любых расчётах. Именно поэтому, кстати, время Unix — это число секунд с 1 января 1970 года, но с поправкой на високосные секунды.

Вообще, исторических казусов предостаточно.

Пользователь системы с часовым поясом Asia/Shanghai однажды пожаловался на следующий код на Java:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

Кажется, что между 23:54:07 31 декабря 1927 года и 23:54:08 того же дня секунда разницы. В реальности программа показывала 6 минут: в TZDB версии 2013a выводится 358 секунд, в 2014f — 344 секунды.

Происходит так, потому что 1927 год для Шанхая был богат на события. Город попал под контроль Национального правительства Китайской Республики, которое 12 апреля запретило коммунистическую партию и устроило резню. Шанхай объявили частью Китайской Республики и поменяли часовой пояс на GMT+8 вместо особого местного, чтобы показать единство Китая. В полночь с 31 декабря 1927 года по 1 января 1928 года стрелки часов перевели на 5 минут 52 секунды назад.

Понятно, что почти всегда в сутках ровно 24 часа. Но возможны неожиданности любого размера: от целого числа часов до произвольного числа секунд и минут.

Заблуждение 3. В месяце 30 дней

Грубые ошибки случаются даже в мелочах.

В 2017 году выяснилось, что минтруда штата Вермонт собрало лишних $26 тыс. на пособия по безработице из-за бага округления в своей системе. Систему написали в 2008 году и лишь при модернизации заметили ошибку.

По закону Вермонта министерство труда получает с работодателя пеню 1,5 % в месяц за неоплаченные взносы. Если в месяце 30 дней, то система корректно считала 1,5 %, но в 31-дневных, коих в году 7 штук, взимала больше положенного. В реальных суммах ошибка была не настолько фатальной, почему, наверное, и продержалась так долго. За $1000 задолженности за год набегало лишних $2,5.

Другой очевидный исторический пример — это сентябрь 1752 года, который даже отражён в рукодстве операционной системы Plan 9 рекомендацией попробовать в утилите cal команду cal sep 1752. В ответ программа выдаст что-то неожиданное.

Заблуждения программистов о времени - 4

Чаще всего датой перехода на григорианский календарь называют 15 октября 1582 года, когда его впервые ввёл римский папа Григорий XIII в католических странах. В григорианском календаре средняя длина года составляет не 365,25 дня, как это было ранее в юлианском, а 365,2425, на 10 минут 48 секунд короче. Достигается это коррекциями алгоритма выбора високосных годов.

Из-за протестантской Реформации на новый календарь даже западноевропейские страны перешли не сразу.

cal — это утилита для Unix-подобных систем, она выводит в терминал календарь любого месяца или года. Программа корректно отображает 1752 год с точки зрения Британской империи, частью которой на тот момент были поселения в Северной Америке. В сентябре того года для будущих США после среды, 2 сентября, наступил четверг, 14 сентября — произошла коррекция в 11 дней.

Россия перешла на григорианский календарь в 1918 году с прыжком в 13 дней: после 31 января сразу наступило 14 февраля. Жить с разницей в почти две недели с остальной Европой было неудобно. Например, в 1908 году из-за разницы в каледарях сборная Российской империи опоздала на олимпиаду в Лондоне, и соревнования стрелков уже успели закончиться.

Разные страны переходили на григорианский календарь в разное время. Вопрос касается не только отдалённых веков, которые учитывать не придётся. Саудовская Аравия перешла (для повседневных целей) на григорианское летоисчисление всего шесть лет назад. После 28 дня месяца зу-ль-хиджа 1437 года у Саудитов наступило 1 октября 2016.

По юлианскому календарю продолжают жить монастыри горы Афон. Иногда происходил обратный процесс: с григорианского календаря страна переходила обратно на юлианский, создавая месяцы длиннее 30 дней. К примеру, Литовская губерния в 1800 году после 11 января вернулась в 1 января. Сможет ли любая система корректно сказать, в какой день недели родился человек из той эпохи?

Наконец, каждый год случается 28- или 29-дневный февраль.

Заблуждение 4. За сутки сменится 24 различных значения часа, каждый — один раз

Очевидно, что в день с переводом стрелок на летнее или зимнее время на часах случится странное: вместо двух часов ночи сразу наступит три или промежуток с 1:59 по 3:00 мир якобы проживёт дважды. Во сколько нужно разбудить человека, если он ставит будильник на полтретьего?

Выбор времени перевода стрелок не универсален. Например, в Чили и Иране переход происходит в полночь: после 23:59:59 наступает 1:00:00. Также подобная схема применялась в Румынии по 1996 год или в Бразилии по 2018.

Часто именно к 00:00:00 привязывают многие события обозначения наступления нового дня, поэтому нужно быть готовым к тому, что полночь (или любой другой час дня) не наступит никогда. NSDateFormatter в iOS не позднее версии 6 знает, что полночь в Бразилии в один день года не существует.

Заблуждение 5: Структура недели универсальна

Неделя начинается с понедельника в большинстве европейских стран, многих странах Азии и островных государствах Тихого океана. Именно с понедельника неделя начинается в стандарте ISO 8601. С воскресенья неделя начинается в Америках, Японии и Филиппинах. Часть Ближнего Востока считает началом недели субботу.

Заблуждения программистов о времени - 5
День недели в разных странах: понедельник (персиковый), пятница (фуксия), суббота (зелёный), воскресенье (синий). Saeed.gnu

Перевес вовсе не за понедельниками. 67 стран мира с населением около 4 млрд человек начинают неделю с воскресенья, 160 стран и 3,3 млрд — с понедельника. Случаются исключения для конкретных применений. Хотя в остальном в США неделя начинается с воскресенья, календарь для вещания радиопередач стандартизирован для работы с понедельника.

Структура выходных также отличается в зависимости от страны и религии. Если христиане посещают церковь в воскресенье, то шестьдесят вторая сура Корана предписывает собираться на джума-намаз в пятничный день. Соответственно, многие мусульманские страны в качестве выходного дня задали четверг и пятницу. Часть из них (к примеру, Саудовская Аравия в 2013 году) постепенно сдвинула выходные на пятницу и субботу, чтобы лучше координировать работу финансовых сервисов с остальным миром.

Заблуждения программистов о времени - 6
Рабочая неделя в разных странах мира: понедельник – пятница (серо-синий), понедельник – суббота (оранжевый), воскресенье – четверг (серый), суббота – четверг (красный), воскресенье – пятница (светло-красный), понедельник – четверг и суббота (фуксия, это Бруней и не выделенная на карте провинция Ачех Индонезии), смешанно (циановый, Малайзия)

Выходные и рабочая неделя могут прерываться. К примеру, в Брунее работают с понедельника по четверг и в субботу, а отдыхают в пятницу и воскресенье.

К счастью, на данный момент неделя везде семидневная.

Впрочем, каких-то двести лет назад французские апологеты республиканского календаря не без энтузиазма продвигали идею о неделях-декадах, чтобы навсегда забыть настолько противное прошлое старого порядка. Три декады образовывали месяц, 12 месяцев — год, лишние 5–6 дней добавляли к концу года. Необычный календарь приняли 24 октября 1793 года, 1 января 1806 года Франция вернулась на григорианский с 7-дневными неделями. Но и в те недолгие 12 лет декады во многом игнорировали и продолжали следовать привычным христианским традициям.

Заблуждение 6: Структура месяца универсальна

Чаще всего (в том числе в исламском лунном календаре) месяц длится от 28 до 31 дня. Исключение: 5–6 дневный месяц Пикучи-Набот в коптском календаре, который использует Коптская православная церковь, наиболее распространённая в Египте.

Для возделывания земли исламский календарь не годится: он оторван от астрономических сезонов и ежегодно смещается относительно солнечного года на 10–11 дней, поскольку основан на наблюдениях за луной. Сутки длятся 29 или 30 дней. Традиционно если вечером 29-го дня Луна видна на небе, то следующие сутки будут началом нового месяца. Если нет, то это будет 30-й день.

Это значит, что решение о длине месяца в исламском календаре принимает некое ответственное лицо или орган, всё зависит от местных условий и методов наблюдения, а предсказать что-то заранее невозможно (или возможно, не неприемлемо по религиозным соображениям). Попытки объединиться и навести порядок продолжаются.

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

Заблуждение 7: RFC 3339 и ISO 8601 — это одно и то же.

Международный стандарт ISO 8601 описывает форматы даты и времени для использования в международном контексте. Это именно тот стандарт, который рекомендует записывать даты как 2022-12-04. Стандарт разработала Международная организация по стандартизации.

Инженерный совет Интернета адаптировал ISO 8601 для использования в протоколах и стандартах Интернета и опубликовал его как RFC 3339. Стандарты схожи, иногда возникают вопросы, насколько сильно они отличаются.

RFC 3339 — это подмножество, профиль ISO 8601 с некоторыми различиями. К примеру, ISO 8601 требует отделять время суток от даты буквой T (2022-12-04T10:00:00Z), а в RFC 3339 допустим пробел (2022-12-04 10:00:00Z). ISO 8601 допускает много опций с припиской «по соглашению», RFC 3339 — это профиль, который ограничивает общий набор до минимума.

Заблуждения программистов о времени - 7
ijmacd.github.com

Сравнение двух стандартов умещается в длинную таблицу.

Заблуждение 8: Часовых поясов не больше 24

Часовые пояса обычно представлены как сдвиг в целом числе часов от Гринвича. Москва, к примеру, живёт в часовом поясе MSK или UTC+03:00.

Заблуждения программистов о времени - 8
Карта часовых поясов мира, TimeZonesBoy

Логично ожидать, что суммарно часовых поясов будет ну никак не больше 24. Но это справедливо разве что для географического определения термина — в нём географические пояса нарезают Землю на 24 полоски шириной 15 °.

Реальный мир живёт административными часовыми поясами. Их может быть сколько угодно, поскольку у людей есть собственные интересы. Размер сдвига бывает не только целым числом часов.

Заблуждения программистов о времени - 9
Хотелки жителей тихоокеанских островов заставили изогнуться линию перемены дат

Линия перемены дат даёт три лишних часовых пояса. Дело в том, что часть островных государств находится в Южном полушарии, за линией перемены даты, но для простоты хочет оставаться в будущем дне, а не в прошлом. Остров Чатем живёт в UTC+12:45 или UTC+13:45 летом, Токелау — в UTC+13:00. Острова Лайн государства Кирибати живут в часовом поясе UTC+14:00, который с разницей в сутки совпадает с часовым поясом UTC−10:00. Это значит, что на островах Лайн то же время суток, что и на Гавайских, просто там уже следующий день.

Заблуждения программистов о времени - 10
В островном государстве Самоа с его часовым поясом UTC+13:00 возможно встретить Новый год, затем доплыть до Американского Самоа и отпраздновать ещё раз — на этой американской территории часовой пояс UTC−11:00, ровно в сутки разницы. Жители Самоа выбрали себе такой часовой пояс, чтобы было удобнее торговать с Австралией

Один и тот же сдвиг означает, что в нём могут находиться разные административные часовые пояса. Зимой YEKT (Екатеринбург, UTC+05:00) совпадает по времени со следующими поясами:

  • AQTT, Актобе, Казахстан.
  • MAWT, Моусон, Антарктида.
  • MHT, Мальдивы.
  • ORAT, Уральск, Казахстан.
  • PKT, Pakistan Standard Time, Пакистан.
  • TFT, французский южный и антарктический часовой пояс.
  • TJT, Таджикистан.
  • TMT, Туркмения.
  • UZT, Узбекистан.
  • E, часовой пояс эхо, общее обозначение UTC+05.

Часовые пояса регулярно добавляются. В России в 2016 году появился отдельный Asia/Tomsk. Часовые пояса часто меняют сдвиг относительно UTC, в 2016 году, например, было 8 случаев.

Часовых поясов больше, чем стран на планете. В списке сайта timeanddate.com 244 штуки. В версии 2022g базы данных TZDB перечислены 352 часовых пояса.

Заблуждение 9: Часовые пояса предсказуемы

Полуофициальный стандарт всё же существует — это база данных Time Zone Database или TZDB. Чаще всего в ней пояс назван по имени крупного города или целой страны. Понятно, что по политическим причинам некоторые не захотят произносить вслух Israel Standard Time.

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

Заблуждения программистов о времени - 11
Безопаснее всего предложить пользователю выбрать населённый пункт, как это сделано в Ubuntu

Часть поясов имеет закрепившиеся названия в английском языке, которые легко могут совпадать. К примеру, американский Eastern Standard Time — это часовой пояс UTC−05:00, в котором живёт Нью-Йорк и Онтарио. Но восток есть у всех, а не только у США. Австралийцы называют свой часовой пояс со сдвигом UTC+10:00 тем же именем Eastern Standard Time.

Часто аббревиатуры названий часовых поясов одинаковы. Что такое CST: Central Standard Time в США, China Standard Time в Китае или кубинское Cuba Standard Time?

Когда территория живёт по летнему времени, технически она меняет свой часовой пояс. К примеру, Техас живёт по Central Standard Time зимой, а летом переключается на Central Daylight Time. Часто пользователи не помнят правильное название или вовсе не задумываются и выбирают CST даже летом. Информационной системе придётся подобное учесть.

При этом ей также придётся не забыть, что провинция Саскачеван в Канаде тоже живёт по Central Standard Time, но на летнее время не переходит. И не вся провинция, а только часть.

Консорциум Всемирной паутины рекомендует не мучиться и хранить часовой пояс как отклонение от UTC. В любом случае разработчику иногда придётся сопоставлять населённый пункт или название часового пояса с отклонением от Гринвича.

И текст лучше всё же сохранить: установить название часового пояса по строке вида Sat, 27 Oct 2012 23:47:57 -0700 невозможно.

Заблуждение 10: Переход на летнее время происходит везде одинаково

В Южном полушарии зима наступает тогда, когда в Северном лето, и наоборот. В Южном полушарии весной, около октября, стрелки часов переводят вперёд, а осенью, около апреля, назад.

Расположенные даже в одном полушарии страны не договорились переводить часы в один и тот же день. В Евросоюзе на зимнее время переходят в 01:00 последнего воскресенья октября, в США — в последнее воскресенье ноября в 02:00.

Переход на зимнее и летнее время везде означает сдвиг на час. Исключение: австралийский остров Лорд-Хау с населением 382 человека. Обычно остров живёт в UTC+10:30. Но губернатор острова зачем-то захотел хоть на полгодика жить в одном с штатом Новый Южный Уэльс часовом поясе UTC+11:00.

Заблуждения программистов о времени - 12
Синим и оранжевым выделены страны или регионы, которые переводят стрелки часов на лето, серым — которые от практики отказались, чёрным — которые не переводили никогда. TimeZonesBoy

Не все страны или их части переводят часы на лето. К примеру, штат Аризона от этой практики отказался в 1968, хотя остальные материковые США сохраняют традицию.

Наконец, иногда страны решают отказаться от перехода на летнее время или ввести эту практику. Правила перехода на летнее время меняются в нескольких странах каждый год.

А ещё решения бывают стремительными: в 2016 году Египет сначала решил ввести переход, а потом, 3 недели спустя, внезапно отказался за три дня до перевода стрелок. Успеет ли любая система обновиться?

По материалам yourcalendarfallacies.com, оригинальных постов Ноа Сассмана (1, 2) и блога Заина Ризви.

Автор:
atomlib

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js