Пользователь
102,0
рейтинг
19 июня 2012 в 16:51

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

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

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

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

Все эти предположения ошибочны
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. Эта публикация составлена под впечатлением от культового поста Патрика Макензи об именах пользователей, который я перечитывал снова и снова на протяжении нескольких лет, и откуда я бесстыдно позаимствовал и структуру, и стиль. Если вы ещё не читали этот шедевр, идите и прочтите прямо сейчас. Обещаю, что вам понравится.
Перевод: Noah Sussman
Анатолий Ализар @alizar
карма
744,5
рейтинг 102,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (212)

  • +16
    Третьего дня работал с партнёркой. Для авторизации нужно было использовать время, менее чем на минуту отличающееся от времени сервера. Беда в том, что время сервера отличалось на полторы минуты от того, что отдают интернет сервера синхронизации.
    • НЛО прилетело и опубликовало эту надпись здесь
      • +2
        Поржал, спасибо :)
      • +2
        Изза Вам подобных время становится многомерным и с внутренними циклами! ;)
  • +32
    Есть (был?) ещё популярный баг с летнем временем. Так что:
    35. Одно и то же время может быть только один раз.
    • +24
      Ну и как следствие
      36. Разница (длительность) между временем окончания чего-либо и началом не может быть отрицательна ;)
      • +10
        Вспоминаем про NTP-сонхронизацию и добавляем ещё пару заблуждений:
        37. Ну ладно, но отрицательная длина интервала не быть больше часа и бывает такое только раз в год.
        • +6
          38. Через 24 часа будет завтра, а 24 часа назад было вчера.

          tomorrow = time.strftime('%Y/%m/%d', time.localtime(time.time()+86400))
          • +1
            Это заблуждение — аналог первого в списке.
        • 0
          Вы не совсем правы. На Linux-е время не уходит назад при использовании NTP-синхронизации + adjtime (по дефолтам).
          Оно может скакнуть назад разово при старте ОС, если включен ntpclient, который как раз выставляет время моментально. Хотя, даже его можно запустить с ключиком -B, который выполнит плавную коррекцию времени.

          Так что, отрицательная длина бывает на не линуксах.
    • 0
      Вообще-то 02:59 ≠ 02:59 DST. Вот то, что не учитывают DST как часть времени — частая проблема. Но тем не менее Вы правы, правило остаётся ложным: коррекция времени при «спешащих» часах всегда возможна.
    • +7
      35 с половиной: Если уж в какой-то стане есть\нету летнее время — то это навсегда.
  • +2
    Да-да. Я помню как в старые добрые времена какого-то пользователя угораздило зайти на мою BBS в последнее воскресенье марта примерно в 01:57. Опаньки и time limit…
  • –8
    А вы сам — программист? А то ведь вы тоже заблуждаетесь насчет 365 дней :)
    • +1
      И в чём заблуждение?
    • +8
      Он — alizar.
      А это перевод. :-)
      • +26
        Я — лох, 2 раза :(
        • +4
          Ну Вы просто меня (и еще 138 человек) дураками выставили. Мы столько сил потратили, чтобы возле топика в явном виде стояло слово «перевод» — а всё равно пофигу, оказывается. :(
          • +1
            Очень похоже на метку «из песочницы», которая, по сути, никакой значимой смысловой нагрузки не несёт, и все привыкли её игнорировать.
            • 0
              Есть разные метки: из песочницы, перевод, режим реабилитации (не помню точно названия). Они несут смысловую нагрузку.
              • +1
                О, во как! Я и вправду подумал, что это метка «из песочницы» и потому автоматом проигнорил всю статусную строку топика, и очень удивился, что это ализар, т.к. подсознательно казалось, что это из песочницы. Метку все же можно как-нибудь улучшить, например добавить к ней иконку перевода, которая сейчас стоти слева от заголовка. Получается две информационных области по обе стороны от заголовка, которые «размазываются». Думаю, объединив их в одну область, будет больший акцент.
                • 0
                  Или сделать другой цвет фона или шрифта у данной метки.
              • 0
                Что-то вроде баннерной слепоты. При первом взгляде на название топика эти метки не замечаются.
                • +1
                  Надо было метки делать другим цветом, чтобы обратить внимание, видимо.
              • 0
                В том-то вся штука, что по привычке эти надписи пролетают мимо глаз.
                Для того, чтобы не пропускать метки — надо узнать, что их несколько, а чтобы узнать, что меток несколько — надо не пропускать их мимо глаз.
          • +3
            Друзья хорошие, дизайнеры, вы считаете что это заметно хоть одной живой душе?
          • +1
            Хреново оно у вас стоит.
          • 0
            о как
            искал внизу статьи ссылку на оригинал или просто указание что перевод
            не нашел, решил что не перевод

            а ы вона куда это засунули, в начале статьи в зголовок еле заметным цветом
            теперь когда вооружен надеюсь смогу быстро это находить
            • 0
              >искал внизу статьи ссылку на оригинал

              Ну если даже искали — так чего же не нашли? Она ведь там есть, слева от слова «alizar».
              • 0
                о боже, и правда
                красная ссылка с именем, с первого раза кажется что ссылка на хабрапрофиль, типа там на ревьювера статьи
                спасибо

                или я слепой или у дизайнеров хабра своё хитрое понятие юзабилити
  • +3
    7. Неделя (месяц) всегда начинается и заканчивается в тот же год.

    Месяц всегда начинается и заканчивается в тот же год. Или я чего-то не понимаю?
    • +7
      Это по нашему календарю, который мы используем. Но это не единственный вариант календаря, который существует и используется :)
      • 0
        Что за календари, интересно, и реализованы ли они хотя бы где-то?
        • +5
          Отвечает Александр Друзь!

          Ответа на ваш вопрос я дать не могу, но про китайский календарь вроде все знают. Если о реализации, то хотя бы вот вам ссылочка: lv.php.net/calendar
        • +2
          О них, например, можно здесь почитать (доступ к каждой через меню слева). Немного аналитики и интересных фактов об использующихся в мире календарях — в этой статье.
        • +2
          Кстати вспомнил тут сегодня — финансовый сектор! Там финансовый год, квартал и.т.д. не совпадают с календарными.
      • +2
        В еврейском календаре год кончается одновременно с окончанием Элула, а начинается 1 Тишрея.
        В некоторых китайских календарях год может начинаться в разные месяца + есть нечто кроме число-месяц-год, есть ли календари, в которых новый год в середине месяца — не знаю.

        В теории-то возможно всё, вот только это имеет значение лишь для функций time_t <-> char*. Вуаля, система ничего не знает о разных календарях.
        • 0
          Если ей не надо резать отчетность по границами месяцев и тому подобные задачи решать — может, и хватит одного to_char, но задач, когда надо про границы привычных интервалов знать более чем достаточно.
          • +1
            А что, в Китае отчетность привязана к китайскому календарю? Бедолаги.
    • 0
      19 июня + месяц = ??
    • +13
      Ох, да. Никогда не любил работать с датами и временем.
  • 0
    >> В сутках всегда 24 часа
    Что, нет?
    • +15
      Когда переводят часы, в сутках либо 23, либо 25 часов )
      • +14
        а еще бывает 24 часа и 1 секунда.
        • 0
          Но это ведь не отражается на таймстампах, верно?
          • 0
            очень даже отразится, когда 2 секунды время не изменяется это может отразиться на всем чем угодно
            • +1
              Ну да, так весь пост про это :)
              • +1
                Ой, не туда :)
                • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Хотел написать, что в таймстэмпах должна учитываться эта дополнительная секунда, но чё-то PHP не подтвердил мои предположения (31 декабря 2008 добавлялась секунда):
              php -r "echo phpversion(), PHP_EOL, strtotime('31-12-2008 23:59:59UTC'), PHP_EOL, strtotime('31-12-2008 23:59:60UTC'), PHP_EOL, strtotime('01-01-2009 00:00:00UTC'), PHP_EOL;"
              5.3.8-pl0-gentoo
              1230767999
              1230768000
              1230768000
      • +8
        Вы всё ещё используете что-то отличное от UTC? Тогда мы идем к вам!
    • –2
      А 12 часовое время AM/PM не оно случаем?
    • +18
      У меня на практике был интересный юзкейс, когда пользователь садился в самолет и летел через несколько часовых поясов с включеным таймером в нашей программе ;)
      • 0
        Чета я не пойму а как влияет время полета на часовые пояса? Одо дело если он хотел узнать местное (см. точное) время, и другое когда засекал время действия (перелет). Таймер ведь правильно всегда работает, он отсчитывает интервал времени независимо от часового пояса итд.
        • 0
          Наверное, это был не настоящий таймер, а что-то вроде цикла, в котором на кажодй итерации высчитывалась разница между начальным временем и текущим, причём не в UTC, а в текущей временной зоне.
          • 0
            =) ну это называется «сам дурак», ни больше ни меньше.
            • +2
              Ну да, так весь пост про это :)
              • +3
                <joke>я там еще пару каментов оставил, можете продолжать</joke>
                • 0
                  Да, но те комментарии не были ответами на мои комментарии ;-)
          • 0
            Нет. Смотрите мой ответ ниже.
        • +2
          Таймер засекал сколько времени проработал сотрудник. Запись привязана к определенной дате. При пересечении поясов получалось так, что сотрудник мог зарепортить более чем 24 часа на определенную дату (все по чесному: начал работать 19 июня и закончил 19 июня). При чем использовать UTCшную дату нельзя, потому как она не будет работать для нормального юзкейса в таймзонах, далеких от Гринвича. В общем классический пример исключения, о котором часто не думают при дизайне таких систем.
          • +1
            Самое интересное, что если бы программа и правда зарегистрировала, что человек проработал за те сутки 25 часов, то это было бы правдой.

            Причём возможно, это далеко не худший способ функционирования подобных программ. Ведь если, в качестве альтернативы, считать рабочие часы, привязавшись к какой-то одной конкретной временной зоне, то могут появиться другого рода «ошибки». Например, если человек улетит на другой край планеты, то его работа начнёт регистрироваться ночью — e.g., 4 часа до полуночи, 4 после. Часть рабочих часов и на выходные так сможет ненароком попасть.
          • 0
            Это называется не таймер, а запоминание даты начала и даты конца работы =) таймер всегда работает правильно, ибо считает количество едениц времени независимо от зоны.
            Я в таком случае просто брал и считал секунды от начала работы и до окончания, затем слал полученное число и с ним уже работал на сервере, чтоб не было привязки к временным зонам, вот у меня был на самом деле таймер =)
    • +1
      А в некоторых моделях времени — они 23 часа 56 минут (звездные сутки).
    • +2
      ещё если брать не нашу планету, а иную систему отсчёта
    • +1
      Астрономией не интересовались? Кроме DST переходов (23/25 часов) и високосных секунд, если есть связь с реальным вращением Солнца, то нужно помнить, что средние солнечные сутки равны 24 часам. А в течение года длительность суток колеблется в пределах ±28 секунд. И наступление новых суток происходит не всегда в 00:00. Но вряд ли об этом в статье — астрономия более специфическая вещь.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Вот исполнится тебе 4 годика, тогда узнаешь всю правду
      • НЛО прилетело и опубликовало эту надпись здесь
        • +2
          Не изворачивайся.
          Фраза «В феврале всегда 28 дней.» означает, что в феврале ровно 28 дней, не меньше и не больше(!).
          А значит, этот пункт имеет место быть в списке ложных утверждений.
          Ты же переделал её в более мягкую форму, допуская другое количество дней.
          • –2
            Фраза «В феврале всегда 28 дней» означает, что в феврале всегда можно насчитать 28 дней. Мысль топика будет выражать фраза «В феврале всегда только 28 дней».
            • +8
              Вам всегда 5 лет. Нормально же, не так ли?
            • +1
              Пройдёт ли успешно этот тест?
              Assert.AreEqual(28, DateTime.DaysInMonth(DateTime.Now.Year, 2));
            • 0
              За что заминусовали — непонятно. Правда неоднозначность.
  • +29
    Ещё нужно добавить:

    35) На машине пользователя всегда будут актуальные обновлённые таймзоны.
    • 0
      к серверам это тоже относится
      • 0
        Вот это я, с недавних пор, проверяю всегда =)
      • 0
        Серверы ещё ладно, они зачастую хоть подключены к сети и имеют возможность автообновляться.
        Особенно тяжко в этом отношении девайсам на всяких экзотических ОС, для которыми обновления если и выпускаются, то часто никто не утруждается их установкой. Впрочем, то же по большей части относится и к популярным мобильным платформам.
    • +2
      Мало того, этот пункт до сих пор нам аукается с авторизацией вконтакте. Они ставят куку на час…
      • +3
        Самое страшное, что «в часах в нижнем углу время правильное!» И ведь не поспоришь… Мы вот так же у одного клиента решали проблему, пока не выяснили, что у него родное правительство недавно поменяло таймзоны, а апдейты у него отключены, ибо чо там такого может быть важного. В итоге получилась разница в два часа: один час из за смены таймзоны, второй — из-за того, что он крыжик поставил «переход на летнее время». Зато на часах в винде правильное время!
    • +2
      Я тоже люблю попаранойить, и часто при разработке (допуская при этом типовые ошибки типа if(a=1)) задумываюсь о том, что будет если диск будет полным, что будет если систему запустят, когда файлуха будет в рид-онли режиме, что будет если время будет выставлено иначе, что будет если с системы вдруг удалят какую-нибудь утилитку типа find или chmod, что будет если модуль обработки информации запустят, а модуль хранения (который получает информацию) — не запустят…

      И получается, что чтобы грамотно реализовать идею минимального ущерба при этих действиях, нужно написать кода больше, чем сама система. Зачем? Вот в Angry Birds тоже время считается, и в тетрисе. И нормально. А для аккуратной реализации всех перечисленных 30+ пунктов нужно больше работы, чем для реалистичного полета курицы.

      Поэтому мне кажется, что более грамотно не пытаться делать нож, которым нельзя порезаться, если вдруг пользователь-админ решит его в задницу засунуть, а просто написать в условиях, что, скажем, клиент и сервер должны синхронизировать время раз в час. При этом система должна «терпеть» небольшую разницу во времени между ними, а в случае невероятной разницы (разные года) — просто не умирать, но имеет право и не работать. Ну не может программный продукт воевать с его администратором и победить. Если уж администратор хочет что-то запороть — у него это получится. Поэтому и лишние затраты на такую оборону — не нужны.
      • +1
        В разных продуктах нужны разные проверки. Там, где куриц в свиней надо кидать, очевидно, нет смысла заморачиваться на всех мелочах. А в системах, где считаются деньги, ошибки с датами могут вылиться в итоге в огромные убытки. Плюс в таких продуктах в документации чётко прописывается, что на сервере ОБЯЗАНО стоять корректное время, корректная таймзона, иначе последствия непредсказуемыми будут. Причём что неприятно, определить изнутри программы, что всё плохо, в таких ситуациях бывает либо очень сложно, либо совсем невозможно.
  • +5
    в п.34 имеется ввиду неочевидность формата (не понятно, это dd/mm/yy или mm/dd/yy), или что-то другое?
    • +1
      и еще y2k
    • 0
      Подозреваю что да, у нас например dd/mm/yyyy а у тех же педосов mm/dd/yyyy и каждый вводит по своему, даже если указать подсказку
  • +7
    Гибрид поста про имена и поста про время:

    36. У человека всегда есть дата рождения.
    36а. У человека есть хотя бы месяц или год рождения.
    37. Любой документ (паспорт гражданина и т.п.) всегда содержит даты, которые реально существуют в календаре.
    • +3
      38. Реальная дата рождения и дата по паспорту совпадают.
      • 0
        Кому может быть интересно хранить оба варианта? Для формальных целей обычно везде указывают ДР по паспорту, для неформальных — реальный.
        • 0
          Тому, кому интересно поймать вас на вранье. Например, банку.
          • 0
            Банк обязан верить тому, что записано в паспорте. Зачем им что-то ещё?
            • 0
              Увы и ах, паспорт не является 100% достоверным источником информации. Верить конечно можно, но гораздо лучше доверять, но проверять
              • +1
                лучше доверять, но проверять

                Каким же образом? Верить на слово? ;-)
                • 0
                  Пока да :)
        • 0
          Ваш комментарий — №39.
    • +1
      Пункт 37 верен, в противном случае, как я понимаю, документ должен считаться недействительным, а, следовательно, и не документом вовсе.
      • +3
        Пример: паспортистка ошиблась, написала случайно 31 июня. Еще когда паспорта и прочие справки от руки перьевой ручкой заполнялись. И человек будет с этим жить много лет и однажды прийдет пользоваться вашей системой.
        • +2
          То, что в паспортах раньше частенько ошибались, например, в написании фамилий — дело известное. А случай с датой основан на реальных событиях? Что-то мне подсказывает, что у такого человека будет ОЧЕНЬ много проблем ВЕЗДЕ, так что скорее всего он все-таки успеет десять раз поменять паспорт, прежде чем заинтересоваться чьей-то системой.
          • +1
            Насчет именно паспорта — не помню. Но такие ситуации со справками — были. Такие ошибки встречаются с очень старыми документами (в том числе дореволюционными), у людей из глубинки и т.п.
            Я для себя вывел правило — если какие-то даты вводятся в систему из документов, которые приносит гражданин, то надо быть готовым к тому, что эти даты будут неполные (только месяц и год, например) или несуществующие.
          • 0
            У моего деда на протяжении многих лет день рождения по паспорту 1 ноября, а на самом деле — 1 декабря. Никогда дед не отзывался об этом, как о проблеме.
            • +4
              31 июня не существует. Ваш К. О.
              • +1
                А я уже сомневаюсь, можно ли утверждать, что 31 июня не существует :)
              • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            Что-то мне подсказывает, что у такого человека будет ОЧЕНЬ много проблем ВЕЗДЕ,

            Что-то мне подсказывает, что далеко не везде, а в основном только там, где время вводят в ИС, проверяющих дату на валидность в принципе. Либо там где очень внимательные и при этом злые операторы.
          • +2
            Наш президент (Лукашенко) поменял дату своего рождения, чтобы ДР у него был в тот же день, что и у сына Коленьки. Надеюсь, это доставило ему пару багов.
            • +1
              … и тем самым раскрыл баг, как можно уклоняться от призыва, быстренько перескочив с 17 лет (за день до ДР) сразу в 27!
          • +1
            Бывает. Особенно в старых советских документах — всяких там справках, актах.
          • –1
            Моей жене в паспорте ошиблись на 1 год. И ничего, никаких проблем нет. Никто же не требует свидетельство о рождении, когда уже есть паспорт.
            • 0
              У моих родителях паспортистка при отметке о браке умудрилась написать им разницу в год!!! Потом при замене паспортов уже правили по свидетельству о браке.

              Бабушке по отцу в документах писали то Григорьевна, то Георгиевна.
              «Подумаешь какая разница, Гриша или Жора был отец!» — видимо думали они. Потом несколько раз приходилось доказывать, что не верблюд…

              При регистрации собственности — неверно написали родственные отношения у отца и его тётки. В итоге при вступлении в наследство пришлось доказывать, что он именно ПЛЕМЯННИК, т.к. в написанном была вообще какая-то вода на киселе.

              И т.д. и т.п.
              Это сейчас проблем нет, а если чего — могут возникнуть на пустом месте, типа каких-нить льгот (или наоборот) в зависимости от возраста…
          • 0
            на реальных. я встречал это в базе вкладчиков пенсионного фонда. когда стал думать, что делать — нашел статью, в которой утверждалось, что для даты рождения нужно использовать два поля: строкого типа из паспорта и типа дата — реальная
        • +2
          Такого человека надо посылать менять паспорт.
          • +7
            Я не понимаю, как можно послать менять, например:
            — свидетельство о рождении 1915 года
            — договор 1920 года
            — приказ 1940 года
            • 0
              Человеку с неправильной датой в паспорте от этого легче не станет. Меня в своё время послали менять паспорт из за опечатки в городе рождения. С неправильной датой имеют полное право послать туда же.
              • +1
                Да даже если не пошлют, самому придется идти, когда не сможешь на «госуслугах» каких-нибудь ввести правильные паспортные данные…
      • 0
        В законодательстве, кажется, нет явного требования, чтобы дата была действительной. Есть «дата выдачи» и всё.
        • 0
          А что такое дата? Является ли 31.06.2012 датой?
          • 0
            Может быть интересный вариант, когда в веб-интерфейсе она является корректной датой (число не более 31, месяц не более 12, все ок), а в каком-нибудь более умном обработчике дальше — уже некорректна, и он отказывается процессить этот запрос. Затем программисты видят что исходящих почему-то меньше входящих, подозревают баг, но решают исправить все «скотчем», написав утилитку, которая ищет необработанные запросы, и ставит их в очередь обработки на след. день.

            Такая очередь будет постоянно расти, но пока что мощности сервера хватает, а потом плановый апгрейд и при этом всем вроде кажется что система работает нормально:
            1. Обычные пользователи получают свои данные
            2. Необычные (с 31.06) не получают, но понимают, что сами виноваты, и не бузят, сначала идут исправлять эту ошибку
            3. Программисты видят что в системе есть ошибка, но считают что она неважная, поскольку их workaround вроде как все исправляет.
    • +3
      Ещё:
      "… У человека только ОДНА дата рождения"
      У меня у обоих дедов по две даты рождения: одному на войну хотелось и он её слегка не ту сказал в военкомате, а у второго — в детдоме офф-документы посеяли и написали от балды, не подумав спросить у ребёнка…

      37.а Любой документ отражает дату рождения относительно точно
      Отцу в документах на участок умудрились лишнюю сотню лет приписать…
      • +1
        Офф?
        • 0
          Official
          • +1
            По-русски же пишем.
            • 0
              Это просто жаргонизм, английское слово оправдывает удвоенную «ф». А удвоенная «ф» в свою очередь нужна, чтобы отличаться от иностранной приставки.
              • +1
                Я понимаю, что слов панталоны, фрак, жилет по-русски нет. Но за каким чёртом английское слово, когда есть точно соответствующее, понятное и повсеместно применяемое русское?
    • НЛО прилетело и опубликовало эту надпись здесь
  • +12
    Я б ещё добавил что-то типа
    36) Миллисекундный таймер в 32х битном регистре никогда не переполнится и его значение всегда будет монотонно возрастать.
    • 0
      Едва ли это можно считать реальной проблемой, если регистр всё-таки содержит количество секунд.
      • +2
        В 2038 году расскажете, ок? ;)
    • +3
      Кстати, как раз в тему багов со временем — в ядре линукса время измеряется в jiffies, которые начинаются с нуля и постоянно тикают (увеличиваются). В зависимости от настроек — от 100j в секунду до 1000j. Естественно, чем меньше один тик — тем лучше — точнее будет система. Ну и чем мощнее и быстрее компы, тем меньше можно сделать каждый jiffie.

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

      Решили проблему красиво — ну естественно «административно» признали, что любой код ядра обязан корректно обрабатывать переполнение этого счетчика, и затем начали инициализировать его в -300 секунд. Jiffies начинаются не с нуля, а с очень большого числа, а через 5 минут оно переполняется, и все глючные драйвера тут же сыпятся. Что позволяет тратить 5 минут на один тест, а не полгода.
      • 0
        Молодцы ! !
  • +2
    35. Если два стоящих рядом компьютера показывают одинаковое время после применения GMT — то это не значит что у них одинаковое системное и время и одинаковое GMT < — Жесть, из практики.
    • +3
      Расскажите поподробнее, что это значит.
      • 0
        это не значит что у них одинаковое системное и время
        Тут логический оператор «и». Время у них одинаковое. А системное — не одинаковое.
  • 0
    п.2 и п.4 не соответствует тому, что иногда в феврале 29 дней получается. Вот и пример того, что ошибки бывают везде.
    • +2
      Внимательно не читай, сразу отвечай. Поспешил.
  • +9
    Еще одно заблуждение, в минуте 60 секунд.
    • +1
      А можно поинтересоваться контрпримером?
    • +3
      Да, например в Питоне strftime("%S") может иметь значение от 00 до 61.

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

      Кстати, в следующий раз високосная секунда будет добавлена в этом году, 30 июня, то есть через 11 дней.

      The International Earth Rotation and Reference Systems Service (IERS) in Paris — the grand arbiters of time on our big blue marble — has declared that a leap second will be introduced on 30 June, 2012.


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

      Unlike leap days, UTC leap seconds occur simultaneously worldwide; for example, the leap second on December 31, 2005 23:59:60 UTC was December 31, 2005 18:59:60 (6:59:60 p.m.) in U.S. Eastern Standard Time and January 1, 2006 08:59:60 (a.m.) in Japan Standard Time.
      • 0
        К сожалению, не покажут. Определение Unix-эпохи неверно, ибо оно пропускает високосные секунды, что выльется в -1 при ближайшей синхронизации. А спутники GPS должны вещать о високосной секунде.
        • 0
          Время UNIX согласуется с UTC, в частности, при объявлении високосных секунд UTC соответствующие номера секунд повторяются.
        • 0
          Согласен — но некоторые часы это всё же отображают. Поэтому я и написал о том, что надо выбрать подходящие.
      • 0
        В ДОСе можно указать от 0 до 63 секунд
        некоторые вирусы помечали инфицированные файлы датой с такими секундами.
    • 0
      Ага:
      zdump -v /etc/localtime|grep 2012
      /etc/localtime  Sat Jun 30 23:59:60 2012 UTC = Sun Jul  1 03:59:60 2012 MSK isdst=0 gmtoff=14400
      /etc/localtime  Sun Jul  1 00:00:00 2012 UTC = Sun Jul  1 04:00:00 2012 MSK isdst=0 gmtoff=14400
      
      • 0
        И, кстати, високосные секунды - не редкость
        zdump -v /etc/localtime|grep :60 
        /etc/localtime  Fri Jun 30 23:59:60 1972 UTC = Sat Jul  1 02:59:60 1972 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sun Dec 31 23:59:60 1972 UTC = Mon Jan  1 02:59:60 1973 MSK isdst=0 gmtoff=10800
        /etc/localtime  Mon Dec 31 23:59:60 1973 UTC = Tue Jan  1 02:59:60 1974 MSK isdst=0 gmtoff=10800
        /etc/localtime  Tue Dec 31 23:59:60 1974 UTC = Wed Jan  1 02:59:60 1975 MSK isdst=0 gmtoff=10800
        /etc/localtime  Wed Dec 31 23:59:60 1975 UTC = Thu Jan  1 02:59:60 1976 MSK isdst=0 gmtoff=10800
        /etc/localtime  Fri Dec 31 23:59:60 1976 UTC = Sat Jan  1 02:59:60 1977 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sat Dec 31 23:59:60 1977 UTC = Sun Jan  1 02:59:60 1978 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sun Dec 31 23:59:60 1978 UTC = Mon Jan  1 02:59:60 1979 MSK isdst=0 gmtoff=10800
        /etc/localtime  Mon Dec 31 23:59:60 1979 UTC = Tue Jan  1 02:59:60 1980 MSK isdst=0 gmtoff=10800
        /etc/localtime  Tue Jun 30 23:59:60 1981 UTC = Wed Jul  1 03:59:60 1981 MSD isdst=1 gmtoff=14400
        /etc/localtime  Wed Jun 30 23:59:60 1982 UTC = Thu Jul  1 03:59:60 1982 MSD isdst=1 gmtoff=14400
        /etc/localtime  Thu Jun 30 23:59:60 1983 UTC = Fri Jul  1 03:59:60 1983 MSD isdst=1 gmtoff=14400
        /etc/localtime  Sun Jun 30 23:59:60 1985 UTC = Mon Jul  1 03:59:60 1985 MSD isdst=1 gmtoff=14400
        /etc/localtime  Thu Dec 31 23:59:60 1987 UTC = Fri Jan  1 02:59:60 1988 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sun Dec 31 23:59:60 1989 UTC = Mon Jan  1 02:59:60 1990 MSK isdst=0 gmtoff=10800
        /etc/localtime  Mon Dec 31 23:59:60 1990 UTC = Tue Jan  1 02:59:60 1991 MSK isdst=0 gmtoff=10800
        /etc/localtime  Tue Jun 30 23:59:60 1992 UTC = Wed Jul  1 03:59:60 1992 MSD isdst=1 gmtoff=14400
        /etc/localtime  Wed Jun 30 23:59:60 1993 UTC = Thu Jul  1 03:59:60 1993 MSD isdst=1 gmtoff=14400
        /etc/localtime  Thu Jun 30 23:59:60 1994 UTC = Fri Jul  1 03:59:60 1994 MSD isdst=1 gmtoff=14400
        /etc/localtime  Sun Dec 31 23:59:60 1995 UTC = Mon Jan  1 02:59:60 1996 MSK isdst=0 gmtoff=10800
        /etc/localtime  Mon Jun 30 23:59:60 1997 UTC = Tue Jul  1 03:59:60 1997 MSD isdst=1 gmtoff=14400
        /etc/localtime  Thu Dec 31 23:59:60 1998 UTC = Fri Jan  1 02:59:60 1999 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sat Dec 31 23:59:60 2005 UTC = Sun Jan  1 02:59:60 2006 MSK isdst=0 gmtoff=10800
        /etc/localtime  Wed Dec 31 23:59:60 2008 UTC = Thu Jan  1 02:59:60 2009 MSK isdst=0 gmtoff=10800
        /etc/localtime  Sat Jun 30 23:59:60 2012 UTC = Sun Jul  1 03:59:60 2012 MSK isdst=0 gmtoff=14400
        

        • +1
          Что значит не редкость? Блин, это постоянство
          • 0
            Ну, я к тому, что они чаще високосных годов встречаются.
        • 0
          Что-то мрачное и криптоконспирологическое (из теории тайных заговоров) видится мне в этом списке.

          Как это так получается, что с 1973 года по 1979 год (включительно) високосные секунды случалися каждый год, с 1983 года по 1989 год — каждый второй год, с 1992 года по 1998 год — опять каждый год (кроме 1996 года), а затем вдруг шарах! — между 1998 годом и 2005 годом (семь лет кряду!) ни одной такой секунды?

          Что за астрономические силы прекратили тормозить вращение планеты на целых семь лет?

          Или это в Матрице тормозильник сглючил?
          • +1
            Земля — это же как живой организм. Ось вращения всё время подрагивает, землетрясения, движения тектонических плит, перераспределение плотности в объёме. Вообще, Землю начало конкретно колбасить после столкновения с Теей, ось наклонилась, скорость вращения ускорилась. До этого вращение было более стабильным, а сейчас мы колбасимся как юла, которой дали щелбан, дёргаемся туда-сюда.
          • 0
            Эти секунды образуются из-за взаимодействия уймы псевдослучайных процессов. Поэтому иногда может быть по секунде каждый год, а иногда — десятилетие стабильности.
  • 0
    Согласен, с датой нужно работать аккуратно, хорошо осознавая все тонкости ситуации.
  • +2
    35) Время никогда не идет назад.
    • +1
      Перелет из японии в москву говорит об обратном =)
      • +1
        Ну да, так весь пост про это :)
      • 0
        Это самый простой случай, который решается учетом часовых поясов :)
        • +1
          Я просто на всякий случай обьяснил что имел ввиду человек =)
          • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    ещё: «Конкретные даты всегда легко подсчитать»

    Навеяно статьёй с названием типа «За три дня до Рамадана»
  • +2
    Из яваскрипта:
    ??) setTimeout(function(){},1000) сработает через одну секунду.
    • +5
      ??+1) Выставленный таймер просто обязан рано или поздно сработать.
      • +1
        ??+2) setInterval(), если не перезагружать страницу и не трогать javascript, никогда не останавливается.
        • 0
          Если не трогать javascript, то setInterval никогда не сработает =)
    • 0
      Кстати не факт что через одну, может и через 5
  • +2
    Ещё есть класс проблем с точным временем. Например многие считают, что у системного таймера можно запросить практически любую точность времени. В реальности время в нём дискретно и изменяется шагом по 10-15 миллисекунд. Более мелкие интервалы он не может отмерять (хотя 10ая вижуалстудия каким-то мухлежом может миллисекундные интервалы через него мерить). Очень редко вижу, что кто-то переходит в программе для точных измерений к процессорному времени.
    • 0
      Также процессорное время может измениться при переключении задачи на другой процессор + это ни разу не время, а количество тактов (что важно при изменении частоты).
    • 0
      Честно говоря, даже не знаю что такое процессорное время. Вроде в 8086/88 ничего подобного не было.
    • 0
      10-15 мили — не уверен…
      Мы по работе часто вынуждены считать ОЧЕНЬ точно, так что юзаем mmTimer и тики процессора от запуска программы…
      • 0
        Дочитали бы до конца. Я и говорю про то, что надо использовать процессорное время для обхода ограничения в 10-15 миллисекунд.
    • 0
      C мультимедиа таймером ситуация такая: он в принципе даёт миллисекундное разрешение, но при этом имеет где-то в 100 раз большую погрешность за сутки, в сравнении с аппаратным таймером. Называется «выберите либо то, либо другое».

      Поэтому обеспечить выполнение некоего кода послезавтра в 12:00:00.000 +- 0.001 с средствами Windows фактически невозможно. Это приводит к весьма своеобразным велосипедам при разработке систем телеметрии — доводилось сталкиваться слегка…
      • 0
        Потому Windows не является ОСРВ (кроме WinCE).
  • 0
    Здорово, не знал про Year 2038 problem.
    • +4
      Оооо. Тогда вас нужно срочно уведомить, что таких проблем масса. В том числе и проблема 1 834 652 618 499 343 590 337 415 746 119 712 509 834 124 421 548 072 260 582 352 567 003 896 года.
      • +2
        Если верить тому сайту, Windows их все переживёт.
      • +1
        — Человек — великий оптимист!- умиленно сказал Румфорд.-
        Только подумай — надеется, что наш вид протянет еще десять
        миллионов лет,- как будто человек так же приспособлен к жизни,
        как черепаха!- Он пожал плечами.- Что ж — может, люди и дотянут
        до десятимиллионного года — из чистого упрямства. Как ты
        думаешь?
        — Что?- сказала Беатриса.
        — Угадай, сколько продержится род человеческий?- сказал
        Румфорд.
        Из-за стиснутых зубов Беатрисы прорвался вибрирующий,
        пронзительный, непрерывный звук такой высоты, что человеческое
        ухо его почти не воспринимало. Этот стон звучал жутко,
        угрожающе, как свист стабилизаторов падающей бомбы.
        И грянул взрыв. Беагриса опрокинула кресло, бросилась на
        скелет и швырнула его в угол, так что кости загремели: Она смела
        все начисто со стеллажей Музея Скипа, разбивая экспонаты о
        стены, дробя их об пол.
        Румфорд был ошеломлен.
        — Боже правый,- сказал он.- Что с тобой стряслось?
        — Ах, ты разве не знаешь?- истерически выкрикнула Беатриса.-
        Тебе надо объяснять? Можешь читать мои мысли!
        Румфорд прижал ладони к вискам, широко раскрыл глаза.
        — Помехи и шум — больше ничего не слышу,- сказал он.
        — А чему же там еще быть, кроме шума!- сказала Беатриса.-
        Меня вот-вот выкинут на улицу, мне хлеба купить будет не на что
        — а мой муж посмеивается и предлагает поиграть в угадайку!
        — Да ведь это не _просто_ игра!- сказал Румфорд.- Я
        спрашивал, сколько протянет род человеческий. Мне казалось, что
        это позволит тебе взглянуть на собственные дела как бы в
        перспективе.

        Курт Воннегут, «Сирены Титана»
  • +5
    17. Если часы на сервере и клиенте рассинхронизированы, они по крайней мере всегда рассинхронизированы на постоянное количество секунд.

    image
    • +5
      Это если часы двигаются со скоростью, близкой к скорости света :) Обычная же ситуация, сидишь, а мимо тебя часы пролетают. Оказывается, это тоже не учитывают программисты.
      • +8
        Самая обычная ситуация, часто описывается фразой «три часа пролетели незаметно». :-)
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        GPS между тем, тоже люди пишут. И там эти пролетающие часы далеко не являются фигурой речи :)
  • 0
    Кто-нибудь пояснит как может декабрь 2011 закончиться в 2012 году (пункт 7)?
    • +1
      Декабрь 2011 не может, а вот к примеру тевет — вполне себе.
      • 0
        Эммм. А как можно считать месяца по-еврейски, а года по-григориански?
    • +2
      тут, наверное, сразу много проблем:
      1) 15 декабря — 15 января — это тоже месяц (не календарный, а продолжительность времени)
      2) декабрь в Лос-Анжелесе заканчивается в следующем году по UTC
      3) наверняка, еще что-то есть
  • +5
    Черт возьми, но хотя бы на то, что на сервере и на клиенте время идет в одном направлении, можно положиться?
    • 0
      Нет, время не обязано монотонно возрастать (високосная секунда например).
    • +3
      Нет, например клиент переходит на зимнее время раньше сервера.
    • +1
      Вспомнилось из П. Энтони: «Она вспомнила, как однажды они договорились заниматься любовью в своих естественных состояниях, двигаясь в противоположных потоках времени. Это оказалось возможным… и завораживающим поначалу, хотя для неё не так уж отличалось от их обычных встреч, потому что она не испытывала сильного возбуждения. В результате их постигло разочарование. Но сейчас, когда Ниоба наблюдала за движущимся сквозь толпу задом наперёд Хроносом, тот эпизод во всех подробностях всплыл у неё в памяти».
      • 0
        Это в котором произведении? (Пирс Энтони — плодовитый литератор.)
        • 0
          «С запутанным клубком» из цикла «Воплощения бессмертия».
  • +1
    Обобщение заблуждений, описанных в статье:

    Миф: Когда вы видите в сетевом протоколе поле «время» — это действительно время в какой-то точке пространства.

    Реальность: В сетевом протоколе любого уровня, который расчитан не на специализированное применение в области физики, время — это просто абстрактный идентификатор запроса для специализированных целей для стороны, генерирующей соответствующее значение (для отсчёта таймаутов, помещения запроса в тот или иной диапазон транзакций и т.п.). Соответственно, если вы разрабатываете такой протокол для OTP, имеет смысл задизайнить поле «время» для «времени» по субъективным ощущением удалённой стороны.
  • 0
    Главное заблуждение программистов относительно времени: дедлайн проекта всегда наступает быстрее, чем кажется ;)
    • +3
      Это как раз реальность, но многие верят в обратное.
  • 0
    У автора (не переводчика) неактуально, а вот в России очень даже — можно добавлять ещё один пункт «Жалкому президенту не придёт в голову дать добро на добавление/отмену перехода на летнее/зимнее время» :-)
    • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    В принципе, все пунктики можно вкратце свести к одному:
    0) время — непостоянная штука. Нет надежды на его дискретность, нет надежды на его однонаправленность.
  • 0
    потрясная статья, ей-богу! :)
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      В контексте поста красивее звучало бы
      Книга увидела свет в феврале 2013.

      Да ещё и какого-нибудь 31 числа=)
  • 0
    > 20. У времени нет начала и конца.

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

    Но если при проектировании, например, той же десктопной ОС мы не учтем, например, високосные секунды, мир перевернется?

    А насчет того, что минимальной единицей времени является миллисекунда (наносекунда и т.п) — если уж на то пошло, в принципе не сушествует минимального числа в множестве (0, 1] и мы с этим уже ничего не поделаем.
    • 0
      С учетом того, что спутник просчитали и запустили в 50-ых годах на тех еще смешных вычислительных мощностях, мощностей обычного современного десктопа хватает на очень многие серьезные вещи. Скажем, на обычном десктопе (винда, линукс итд) может крутиться банковская или медицинская система. Грамотно написанная в плане учета високосных секунд. Но какая-то ее часть будет получать время не в юникстайме, а в HH:MM:SS. Затем она что-то планирует сделать как раз в 60-ую секунду (потому что в это время эта секунда будет), 100 раз в секунду проверяет достижение этого времени (и не допускает, что на столь быстром железе время может перескочить, по крайней мере очень тщательное практическое тестирование не позволило заметить ошибку, что время хотя бы раз скакнуло, поэтому проверка выполняется на «равно» а не на «равно или больше» и все успешно работает в миллионе тестов из миллиона), ну и в эту високосную секунду как раз и будет перескок, который завесит всю систему.
  • 0
    Черт побери!)
    Видимо из-за вечерней усталости сначала воспринял список как «вот правила, которых стоит придерживаться», дочитал до 6го пункта и думаю «да ну, что за бред, ей богу», полез в комментарии, ожидая увидеть опровержение, но нет, все тихо-мирно. Хм, окей, читаю дальше, но что-то не тоооо… На 13 пункте все же заподозрил неладное и перечитал заголовок списка — «Все эти предположения ошибочны», фух, аж отлегло от сердца, а то уже батхёрт начался. Лучше утром почитаю =)
  • 0
    (я не программист)

    наводит на мысли что такое количество сложностей должно было породить какую-то библиотеку? или утилиту? или сервис? который большинство из них решает в стандартном виде… разве нет ничего такого? или слишком разные задачи, среды и проблемы
    • 0
      Самое страшное, что каждый пункт в списке, скорее всего, был порожден при создании библиотеки, решающей предыдущие пункты :)
    • 0
      Проблема в том, что в задачах обработки времени нет стандартных задач, — соответственно, и способ их решения будет другой.

      Кому-то нужно, что бы в XVI веке был пропуск в 13 дней, кому-то — что бы в XXм, а кому-то вообще нужно, что бы грегорианский был «экстраполирован» в прошлое. Вот уже появилось несколько десятков (по числу разных дат принятия грегорианского календаря) различий в решении — только по одному ключевому вопросу.
    • 0
      дело не в библиотеке, а в способе пользования оной…
  • –1
    15. People’s names do not contain numbers.

    image
  • 0
    mercury13-kiev.livejournal.com/24668.html — аналогичный список про имена людей в базах данных
  • 0
    Ещё заблуждения:
    * Документы никогда не будут вводиться задним числом
    * Ну хорошо, будут, но тогда при отборе документов по дате они должны выдаваться наравне с документами, оформленными правильной датой
    * Если на форме запрашивается только дата, то будет присваиваться время 00:00
    * При смене часового пояса такие даты будут отображаться верно
  • 0
    9. Ладно, это неправда. Но, по крайней мере, часовой пояс не будет меняться.

    А если на другой планете?

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.