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

:

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

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

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

Все эти предположения ошибочны
1. В сутках всегда 24 часа.
2. В месяце всегда 30 или 31 день.
3. В годах по 365 дней.
4. В феврале всегда 28 дней.
5. Любой 24-часовой период начинается и заканчивается в тот же день (неделю, месяц).
6. Неделя всегда начинается и заканчивается в тот же месяц.
7. Неделя (месяц) всегда начинается и заканчивается в тот же год.
8. Машина, на которой работает программа, всегда будет в часовом поясе GMT.
9. Ладно, это неправда. Но, по крайней мере, часовой пояс не будет меняться.
10. Ну, уж точно часовой пояс не будет меняться, когда программа будет в коммерческой эксплуатации.
11. Системные часы всегда установлены на точное местное время.
12. Системные часы всегда будут установлены на время, которое не сильно отличается от точного местного времени.
13. Если системные часы идут неверно, то они хотя бы всегда будут отличаться на одинаковое количество секунд.
14. Часы на сервере и клиенте всегда показывают одинаковое время.
15. Часы на сервере и клиенте всегда показывают примерно одинаковое время.
16. Ладно, но время на сервере и время на клиенте никогда не будет отличаться на десятилетия.
17. Если часы на сервере и клиенте рассинхронизированы, они по крайней мере всегда рассинхронизированы на постоянное количество секунд.
18. Часы на сервере и клиенте идут в одинаковом часовом поясе.
19. Системные часы никогда не показывают время, которое принадлежит далёкому прошлому или далёкому будущему.
20. У времени нет начала и конца.
21. Одна минута на системных часах имеет в точности такую же продолжительность, как одна минута на любых других часах.
22. Ладно, но продолжительность одной минуты на системных часах будет близка к продолжительности одной минуты на большинстве других часов.
23. Хорошо, но продолжительность одной минуты на системных часах никогда не будет больше, чем час.
24. Да вы шутите.
25. Минимальной единицей времени является одна секунда.
26. Ладно, одна миллисекунда.
27. Никогда не возникнет необходимость переставить системные часы на какое-то значение, отличное от точного местного времени.
28. Ладно, для тестирования может понадобиться переставить системные часы на другое значение, но в коммерческой эксплуатации это никогда не понадобится.
29. Метки времени (time stamps) всегда будут в понятном формате вроде 1339972628 или 133997262837.
30. Метки времени всегда будут в одинаковом формате.
31. У меток времени всегда будет одинаковая степень точности.
32. Метку времени достаточной точности можно считать уникальной.
33. Метка времени показывает время, когда событие действительно произошло.
34. Человекочитаемые даты можно передать в универсальном, всем понятном формате вроде 05/07/11.

Та шутка насчёт минуты, которая длится дольше часа, была шуткой?
Нет.

Был очаровательный баг в старых версиях KVM на CentOS. Виртуальная машина KVM не имела понятия, что работает на физическом оборудовании. Таким образом, если материнская ОС отправляла виртуальную машину в спящий режим, то после пробуждения на системных часах виртуальной машины было такое же время, как в момент засыпания. Например, если VM заснула в 13:00 и вернулась в активное состояние через два часа (в 15:00), то системные часы VM будут всё ещё показывать локальное время 13:00.

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

P.S. Эта публикация составлена под впечатлением от культового поста Патрика Макензи об именах пользователей, который я перечитывал снова и снова на протяжении нескольких лет, и откуда я бесстыдно позаимствовал и структуру, и стиль. Если вы ещё не читали этот шедевр, идите и прочтите прямо сейчас. Обещаю, что вам понравится.