Почему программистам сложно работать со временем в программах
medium

Почему программистам сложно работать со временем в программах

Потому что иногда появляется время 23:59:60

Казалось бы, простая задача: посчитать, сколько времени прошло между двумя датами. Оказывается, сложность этой задачи в некоторых случаях может зашкаливать. Вот небольшой рассказ об этом. Эта статья — не про само программирование, а про сложности, с которыми иногда сталкиваются разработчики при написании программ. Если нужно именно программирование, почитайте статью про гороскоп на питоне.

🤔 На эту статью нас вдохновило видео Тома Скотта из канала Computerphile. Если вы знаете английский, посмотрите оригинальный ролик, там много английского юмора:

Вводные

Допустим, мы пишем программу, которая посчитает, сколько секунд, минут или дней прошло с какого-либо солнечного затмения, наблюдаемого из разных точек Земли за её историю. У нас есть перечень наблюдений: «Такого-то числа в такое-то время в таком-то городе такой-то страны было замечено солнечное затмение» — и этот перечень пополняется с каждым затмением. 

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

Но не всё так просто. 

Почему программистам сложно работать со временем в программах

Нестандартные часовые пояса

Из школьного курса географии мы знаем, что:

  • земной шар делится на часовые пояса;
  • в каждом часовом поясе — своё время;
  • для единой точки отсчёта используют нулевой меридиан в Гринвиче (его называют UTC);
  • есть единый список часовых поясов, которым пользуются все желающие.

Сложность в том, что не во всех странах время совпадает с тем, которое должно быть в этом часовом поясе. Например, у Австралии своё время — UTC+9:30. Это значит, что там на 9 с половиной часов больше, чем на нулевом меридиане. Такое дробное значение часового пояса вносит хаос в наши таблицы, но пока можно справляться.

Кроме Австралии есть ещё несколько стран со своим временем, например Непал (UTC+5:45), Индия (UTC+5:30) или Канада (UTC−3:30). Чтобы перейти на своё время, стране не нужно это ни с кем согласовывать — она просто решает это внутри себя, а потом объявляет всем остальным.

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

Почему программистам сложно работать со временем в программах

Летнее и зимнее время

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

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

Отдельно нужно помнить, что летнее и зимнее время в разных полушариях меняется местами. Когда в северном полушарии страны переходят на зимнее время, в южном наступает летнее время, и наоборот. И это тоже нужно учесть при разработке софта :-)

Но бывает так, что страна решает отказаться от перехода на зимнее или на летнее время — как Россия в 2011 году. Это значит, что все программы, которые работают со временем, должны заранее обновиться, чтобы всё дальше считалось точно. 

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

Почему программистам сложно работать со временем в программах

Внезапная смена даты

Иногда бывает так, что страны, которые расположены возле линии перемены дат, могут пропустить день. Например, Самоа однажды объявила всем, что у них после 29 декабря 2011 года будет сразу 31 декабря — так им проще торговать с Австралией.

Поэтому нам нужно постоянно отслеживать страны возле линии перемены дат, не собираются ли они сделать что-то подобное снова. Если собираются — вносим это изменение в код программы, чтобы она продолжила считать всё правильно.

Почему программистам сложно работать со временем в программах

Политическая обстановка

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

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

Почему программистам сложно работать со временем в программах

Исторические календари

Постепенно подбираемся к сложным вопросам — а как считать время, которое было раньше, в старых календарях? Тогда ведь тоже фиксировали затмения, там есть много ценных данных. Все тонкости переходов нужно тоже учесть. 

Например, в одной стране при переходе от юлианского к григорианскому календарю просто прибавили три недели к дате с какого-то момента в 18-м веке. В другой сделали то же самое, но не в 18-м веке, а лет 40 назад. Сюда же добавляется русский календарь со старым и новым стилем — и это тоже нужно учитывать в программе, если мы хотим, чтобы она находила правильное расстояние между событиями.

Решение — добавить в программу все старые календари и правила перехода между датами для каждой страны.

Отдельно нужно ещё учитывать разность в календарях — откуда начинался отсчёт нового года в каждой стране в разное время. Например, до 17-го века в Англии год начинался 25 марта. Это значит, что даты шли так:23 марта 1509 → 24 марта 1509 → 25 марта 1510 → 26 марта 1510 → … → 31 декабря 1510 → 1 января 1510 →…

Почему программистам сложно работать со временем в программах

Продвинутый уровень — високосная секунда

До этого момента мы говорили только про дни и часы, но что, если у нас стоит задача посчитать прошедшее время с точностью до секунды? И здесь тоже всё сложно: из-за неравномерного вращения Земли у нас время от времени появляются високосные секунды. 

Чтобы наша программа точно учитывала время, она должна получить сигнал от приборов или от сервера астрофизиков, что в мире прошла високосная секунда. И в этот момент внутренние часы после, например, 23:59:59 показывают 23:59:60! 

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

Почему программистам сложно работать со временем в программах

Что дальше

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

Художник:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Алина Грызлова

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
medium