Pull to refresh

Comments 100

А еще время можно кодировать в значения OLE-автоматизации. Это, например, обеспечивает независимость программного кода от вида БД.
Прокомментируйте, плиз, кто заминусовал.
Можно закодировать время в тип double:

double d;

Параметр d является числом двойной точности с плавающей запятой, представляющим дату как число дней до или после базовой даты, полуночи 30 декабря 1899 г. Знак и целочисленная часть d кодируют дату как положительное или отрицательное смещение дня от 30 декабря 1899 г., а абсолютное значение дробной части d кодирует время суток как дробную часть смещения дня от полуночи. Значение параметра d должно лежать в диапазоне от -657435,0 до +2958466,0. (определение взято с MSDN)

В .NET даже встренные функции есть для такого представления:
ToOADate()
FromOADate(double d)
(по-моему, в билдере тоже были, хотя память может мне изменять)

К чему нужна эта свистопляска? Ну, в первом посте я об этом упомянул. Вместо поля типа TimeStamp (и иже с ним) в таблице имеем поле типа Double, котрое не зависит от региональных стандартов и т.п.
да, в VCL тоже TDateTime даблом представляется. Но с часовым поясом оно или нет, никак не зависит от способа хранения.
Это верно, часовой пояс не учитывается.
Не помешало бы придумать свое правило преобразования в double с блекджеком и шлюхами учетом часового пояса.
Это я к тому, что нет принципиальной разницы, в целом хранить, как unix_time, или в double.

Правда юниксовое время с точностью до секунд по стандарту, а в double без проблем миллисекунды помещаются
Лично мне double удобнее, т.к. в основном пишу на C#. Ну и, еще, double универсальнее, чтоли:)
У даблов есть проблема сравнения на равенство, надеюсь вы в курсе :)
В даблах будем только хранить, а оперировать DataTime.
Данно описание, как и Mono показывают ужасную особенность на отрицательных числах:

DateTime dt1 = DateTime.FromOADate(0.1);
DateTime dt2 = DateTime.FromOADate(-0.1);
Console.WriteLine( dt1 == dt2 ); // True
dt1 = DateTime.FromOADate(-10.1);
dt2 = DateTime.FromOADate(-10.2);
Console.WriteLine( -10.1 < -10.2 ); // False
Console.WriteLine( dt1 < dt2 ); // True


Да, может даты до 1899 и не особо нужны, но иметь в виду стоит.
Для сравнения дат используется функция DateTime.Compare(DateTime t1, DateTime t2).
В программе — это то ясно. А вот в БД ORDER BY уже не применить.
Давайте еще придумаем, что делать с устройствами, который автоматом в последнее воскресенье октября перейдут на зимнее время, которое у нас Медведев отменил. Все обновляемые системы, понятное дело, получат апдейт и заработают как надо. А в остальных случаях что делать? На какую временную зону перейти посоветуете?
Андрей, поясните ваш комментарий, пожалуйста. Почему именно GMT+4?
Ну с GMT+4 я погорячился. Просто Антон из Москвы, поэтому +4. Стандартное (домедведевское) Europe/Moscow отличается от UTC на 3 часа зимой и на 4 часа летом. Многие библиотеки учитывают DST, не зная что оно отменено, и переведут часы осенью назад (осень — обратно). После нового декрета о времени правильное «московское» время всегда будет на 4 часа позже UTC, т.е. когда на Гринвиче полночь, в Москве 04:00. А на необновленных устройствах и системах, которые не знают об отмене DST, будет 03:00.

Если поставить другую зону GMT+4, к примеру ОАЭ, у которых нет DST («летнего времени»), то получится что даже необновленные устройства не будут переводить часы весной и осенью и время всегда будет правильным. Соответственно, если у вас раньше было +5/+6 то надо выбирать зону из списка GMT+6 и тоже без DST.

UFO just landed and posted this here
В России сейчас нет часовго пояса UTC+4
есть UTC+3 (Москва, С.-Петербург, Волгоград, Самара, Ижевск)
а потом сразу идёт UTC+5 (Екатеринбург, Уфа, Челябинск).
Поэтому для московского времени выбрать соседний российский часовой пояс не вариант. Придётся выбирать часовой пояс другого государства с UTC+4 (как пример Грузия, ОАЭ), пока не будут пропатчены российские часовые пояса в самой системе.
Если ось непропатченная, то вроде самарское зимнее время должно быть UTC +4
Совершенно верно. Самарское и Ижевское стандартное время раньше было UTC+4 (пока их к московскому не присоединили).
Но вот только даже когда такой пояс в России был, в Windows его долгие-долгие годы всё равно не было (и нет). Поэтому жителям этих регионов приходилось в Windows выбирать часовой пояс Ереван (Армения) или Баку (Азербайджан).
Это ещё раз камень в огород Micirsoft, которая обновления для часовых поясов России обновлять не торопится.
А для остальных систем есть патчи?
Не понял. Про какие системы идёт речь и про какие патчи?
По сути, в России будет введена зона GMT+0400 (вместо GMT+0300) и отменен переход на летнее время. Значит, для старых устройств надо ставить страну, также, находящуюся в зоне GMT+0400 и расположенную недалеко от экватора (там переход на летнее время не имеет смысла).
Да. Будет. А для Москвы оно будет называться MSK или MSD? Или еще как-то?
Есть какое-то официальное разъяснение по этому поводу?
[шутка]Я вообще-то в Киеве живу, думал, что все россияне уже в Москву перебрались.[/шутка]

На самом деле я написал алгоритм. Если у вас было GMT+0600, а станет GMT+0700, то ищите соответствующую страну (это, кстати, будет Таиланд).
Давайте еще придумаем, что делать с устройствами, который автоматом в последнее воскресенье октября перейдут на зимнее время
Зачем придумывать? Всё уже придумано в тех странах, в которых нет перехода на летнее время.
зимнее время, которое у нас Медведев отменил
Я требую пруфлинк! Дайте ссылку на нормативный документ (указ президента, федеральный закон, постановление правительства или что-то ещё официальное), в котором было бы закреплено, что в России устанавливается новое время (в частности в Москве UTC+4 и т.д.) и отменяется переход на летнее время (именно так, т.к. зимнего времени просто не существует).
Все предыдущие ораторы, которые заявляли, что «Медведев отменил переход на летнее время и обратно», не смогли мне предоставить ссылки на такой документ. Потому что его на текущий момент просто нет. Официально это ещё не принято и нигде документально не закреплено. Есть только устное заявление президента на какой-то встрече о том, что он намерен сделать такие изменения с часовыми поясами в России, но это пока просто слова, не более. А раз нет законодательного решения, то и нет официального основания в операционных системах и приложениях делать пока какие-то изменения для часовых поясов России.
А в остальных случаях что делать? На какую временную зону перейти посоветуете?
Если вы сейчас живёте по московскому времени, то вам нужно будет перейти на часовой пояс UTC+4 без перехода на летнее время. Если вам нужна привязка к какой-то локации, то для ориентира выбора времени можете взять время в Грузии (Тбилиси), там как раз UTC+4 и нет перехода на летнее время (в Армении и Азербайджане тоже UTC+4, но там есть переход на летнее время, поэтому они для ориентира не подходят).
Ваши ссылки лишь подтверждают мои слова.
Действительно есть Федеральный Закон (107-ФЗ) «Об исчислении времени», он уже подписан и принят, только пока не вступил в силу (вступает в силу 5 августа 2011 года).
Но только в нём нет никакой конкретики, а только общие принципы и положения об исчислении времени.

В этом законе также указано, что конкретные решения о делении регионов РФ на часовые пояса и об исчислении времени в этих часовых поясах устанавливает Правительство РФ. И для этих целей был подготовлен другой документ, а именно Проект постановления Правительства РФ «О составе территорий, образующих каждую часовую зону, и порядке исчисления времени в часовых зонах», в котором:
а) Установливаются часовые зоны, время в которых будет соответствовать бывшему летнему времени на этих территориях.
б) Отменяется сезонный перевод часов.
Планировалось, что этот проект будет рассмотрен, одобрен и подписан уже в июне 2011 и вступит в силу с 1 июля 2011, но этого пока не произошло. Это по-прежнему не официальное постановление а лишь проект, который ещё не одобрен и не подписан.

Таким образом, официально принятого правового акта о новом времени в часовых поясах и об отмене сезонного перевода часов на текущий момент нет.
Статья 4, пункт 4:
Счет часов, минут и секунд в течение календарного года, календарного месяца и календарной недели не изменяется.
Я не юрист, но для меня этот пункт выглядит как утверждение об отсутствии каких бы то ни было переходов на летнее-зимнее время.
Нет, это не означает отсутсвие переходов. Об отсутствии сезонных переводов часов явно сказано только в проекте постановления правительства, которое пока ещё не принято.
Давайте все по порядку.
4/02/1991 Совет министров принял постановление N20, в котором написано:

Принять предложение Государственной комиссии единого времени и эталонных частот СССР об отмене с последнего воскресенья марта 1991 г. действующего постоянно в течение года одночасового превышения применяемого времени над поясным («декретного» часа), предусмотренного постановлением Совета Министров СССР от 24 октября 1980 г. N 925 «О порядке исчисления времени на территории СССР» (СП СССР, 1980 г., N 25, ст. 150; 1984 г., N 29, ст. 161).


Далее. 23/10/1991 Совет республики верховного совета РСФСР принял другое постановление N1790-1:

Констатируя, что реализация Постановления Кабинета Министров СССР от 4 февраля 1991 г. N 20 об отмене действия декретного времени и переводе стрелки часов на 1 час назад 29 сентября 1991 года привела к сокращению продолжительности светового дня на значительной части территории РСФСР, вызвала недовольство населения и привела к увеличению расхода электроэнергии, Совет Республики Верховного Совета РСФСР постановляет:
1. Восстановить декретное время на территории РСФСР.


И наконец последний закон Медведева, о котором говорят выше, гласит в том числе:

Признать утратившим силу Постановление Совета Республики Верховного Совета РСФСР от 23 октября 1991 года N1790-I «Об упорядочении исчисления времени на территории РСФСР» (Ведомости Съезда народных депутатов РСФСР и Верховного Совета РСФСР, 1991, N46, ст. 1551).

— В итоге, будет выполняться постановление совета министров СССР N20 об отмене дискретного времени.

И, вроде, никаких дополнительных постановлений не нужно уже.
В итоге, будет выполняться постановление совета министров СССР N20 об отмене дискретного времени.
Не будет, выходившие после него постановления его отменили, а обратно его в силу никто не возвращал.

Более того сейчас вообще получится Поясное время +2, т.е. декретное время не то что отменится, а наоборот даже усугубится на час.
То есть, какой пояс выбирать-то нужно будет? Я чисто с практической точки зрения. :)
Ну так читайте Проект постановления Правительства РФ «О составе территорий, образующих каждую часовую зону, и порядке исчисления времени в часовых зонах», там всё написано.

Новые часовые пояса в России будут такими:
UTC+3: Калининград
UTC+4: Москва, Санкт-Петербург, Нижний Новгород, Курск, Волгоград, Самара, Ижевск
UTC+6: Екатеринбург, Уфа, Челябинск, Тюмень, Пермь, Курган
UTC+7: Омск, Томск, Новосибирск, Кемерово
UTC+8: Крсноярск, Абакан, Кызыл
UTC+9: Иркутск, Улан-Уде
UTC+10: Чита, Благовещенск, многие районы и округа Якутии (включая сам Якутск).
UTC+11: Владивосток, Хабаровск, Биробиджан, часть Якутии (Верхоянский и Оймяконский районы), часть Сахалинской области (включая весь о.Сахалин и Южные Курилы)
UTC+12: Магадан, Чукотка, Камчатка, часть якутии (Абыйский, Верхнеколымский и Среднеколымский районы), часть Сахалинской области (а именно Северные Курилы).

Везде без перехода на летнее время.

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

А если с привязками к региональным именам часовых поясов, то:

1) в Linux быстро выпустят патч для tzdata, поэтому всё будет очевидно:
— для Москвы нужно будет выбирать московское время;
— для Екатеринбурга — екатеринбургское время;
— для Новосибирска — новосибирское, время;
— для Иркутска — иркутское время;
— для Владивостока — владивостокское время;
и т.д.
И все они будут давать правильное местное время.

2) а пользователи Windows обычно патчей часовых поясов ждут очень долго, поэтому долгое время до выхода этих патчей они будут вынуждены:
* либо самостоятельно ручками в реестре (или через утилиту tzedit.exe) патчить в реестре данные обо всех часовых поясах;
* либо юзать неочевидные костыли:
— для Москвы — выбирать часовой пояс: Тбилиси (Грузия) или Абу-Даби (ОАЭ);
— для Екатеринбурга — выбирать часовой пояс: Бишкек (Киргизия) или Дакка (Бангладеш);
— для Новосибирска — выбирать часовой пояс: Бангкок (Таиланд), Ханой (Вьетнам) или Вьентьян (Лаос);
— для Иркутска — выбирать часовой пояс: Токио (Япония) или Сеул (Южная Корея);
— для Владивостока — выбирать часовой пояс: Хониара (Соломоновы о-ва), Порт-Вила (Вануату) или Нумеа (Новая Каледония);
и т.д.
Якутия и сейчас находится в трёх часовых поясах, а Сахаинская область в двух, их не поделят — они уже поделены.
Как я понял, граница часовых поясов уже была внутри Якутии и Сахалинской области (установлена ранее, ещё в постановлении Правительства Российской Федерации от 8 января 1992 г. № 23 «О порядке исчисления времени на территории Российской Федерации», в замен которого готовится это новое постановление). Однако, эта граница проходила немного иначе, между другими районами. Эту границу действительно не вводят заново, а только немного сдвигают.
> которое у нас Медведев отменил
Вы таким образом тонко намекнули, что в этом виноват он, и что этого делать не стоило? Так вот, сделать это стоило уже давно
MySQL хранит время таким образом не потому, что хотелось усложнить жизнь программистам.
Помимо возможности использовать строковую сортировку, такой формат позволяет использовать выборки вида %-d-m%, а также спокойно (без пляски со знаками и внезапного шаманства при некоторых условиях) хранить любые даты с Р.Х., а не с 1970 года.
Когда MySQL только разрабатывался, это был весьма свежий стандарт, так что уверен, что вы правы.
Я лишь перечислил основные преимущества этого формата перед числом.
Почти всегда имеет смысл обернуть системные вызовы в свою функцию. В дальнейшем в эту функцию можно добавить управляемый сдвиг — как минимум, это будет полезно при прогоне тестов, когда нужно будет сымитировать «прошел год».
MySQL (по крайней мере, 4.x и 5.x) хранит столбцы типа DATETIME в виде строки «YYYY-MM-DD HH:MM:SS».

Пруф? То, что mysql принимает и отдает поля типа datetime как строку, не значит, что он ее так же и хранит.
Конечно же, MySQL не хранит DATE, TIME или DATETIME как строки.

DATETIME хранится как два четырёхбайтовых целых числа: YYYY×10000 + MM×100 + DD и HH×10000 + MM×100 + SS. Вероятно, именно это имел в виду автор статьи, говоря о хранении DATETIME как YYYYMMDD HHMMSS.
Не следует разделять понятия UTC и GMT — они оба идут от нулевого меридиана и в обычной жизни это синонимы и взаимозаменяемые термины.
Единственная разница — наличие високосных секунд в UTC и синхронизация по атомным часам, но она в большинстве случаев пренебрежимо мала.
Спасибо, именно этого мне не хватило в статье, остальное я и так знал :)
> Не следует разделять понятия UTC и GMT

И тем не менее шкала времени GMT уже мертва. Она нигде не поддерживается. Время по GMT сейчас взять просто неоткуда. Все источники точного времени (и GPS-спутники, и NTP-серверы) сейчас сообщают только время по шкале UTC.
Начиная с 1972 для всех гражданских нужд используется шкала UTC. Поэтому сейчас точное время и смещение часовых поясов правильно обозначать именно через UTC, а использовать в обозначении времени GMT — уже неправильно. Я ещё понимаю, люди в прошлом веке по старой привычке продолжали обозначать время через GMT, но уж сейчас это совсем моветон.

GMT устарел и более не используется. Сейчас есть только UTC, никаких GMT.

Microsoft и тот одумался, и наконец-то в последних версиях своей ОС (Windows 7 и Windows Server 2008 R2) в настройках даты/времени стал обозначать часовые пояса правильно — через UTC. А до этого во всех предыдущих версиях Windows (включая Vista и Windows Server 2008) они использовали неверное обозначение через GMT.
>И тем не менее шкала времени GMT уже мертва. Она нигде не поддерживается.

Ну прямо-таки нигде. В Java, например, в стандартном API (java.util.TimeZone) все еще можно работать с GMT.
Не знаю как там, но во многих местах (приложениях/сервисах/утилитах) обозначение GMT сейчас используется ошибочно. В реальности там следует везде использовать UTC, а они пишут GMT.
Этим грешат даже весьма именитые гиганты, такие как Google (см. настройки часовых поясов в Google Calendar).

Реально обозначение GMT для времени сейчас может оправданно выглядеть только в каких-то старых книгах (до 80-х годов прошлого века) или в функциях для работы с датами до 1972-го года. Во всех остальных местах для обозначения времени и часовых поясов (а также относительного сдвига времени и сдвига часовых поясов) сейчас следует использовать только UT0, UT1, UT2 (для астрономических нужд) и UTC (для гражданских и всех прочих нужд).
В современных обозначениях времени никаких GMT быть вообще не должно.
Не обязательно было утруждать себя перепечатыванием своего же комментария.
Это же топик не том, что должно быть в идеальном мире, а о том, что может встретиться программисту в реальной жизни. Вы же сами выше привели пример с MS, которые лишь недавно перешли на UTC обозначение.
MySQL (по крайней мере, 4.x и 5.x) хранит столбцы типа DATETIME в виде строки «YYYY-MM-DD HH:MM:SS».

Не совсем так, строка упакована 8 байт:
DATETIME: Eight bytes:
    A four-byte integer packed as YYYY×10000 + MM×100 + DD
    A four-byte integer packed as HH×10000 + MM×100 + SS
Хорошо, давайте исправим.
Я вижу проблему 429497 года. Можно добавить в Википедию рядом с проблемами 2038 и 10000 годов :)
Статья очень полезная по сути, но стиль оставил у меня впечатление не очень хорошего перевода с английского (слишком дословного, возможно, недопричёсанного машинного). «Часовые пояса относятся к уровню презентации» — по-моему, это называется «уровень представления» (presentation level). Вроде бы, у некоторых программистов уже принято говорить «пойнтер» и «аррэй» вместо «указатель» и «массив», но лично мне это очень не нравится =\ «Часы внутри спутников GPS регулируются для преодоления эффектов относительности.» — а вот тут у физиков уже прижилось иноязычное название «релятивистские эффекты». А вот это: «Это компромисс: вы не можете как-либо выразить високосную секунду в ваших системных часах и ваше время гарантированно пойдёт в обратную сторону.» — я вообще не до конца понял, но могу лишь предположить, что речь о том, что не во всяких системных часах можно представить время, например, 60.5 с, для чего оно и заменяется на повтор 59.5 с.
Это не стиль, это и есть полу-машинный и достаточно корявый перевод с английского (обратите внимание на значок «z — я» возле заголовка, это топик-перевод).
Что касается «Это компромисс: вы не можете как-либо выразить високосную секунду в ваших системных часах и ваше время гарантированно пойдёт в обратную сторону.»: если вы работаете с системным временем и столкнулись с описанной ситуацией, то никакого способа отличить «первые» 59.5 от «вторых» нет. Т.е. если ваше приложение выполняет 4 раза в секунду какую-либо операцию, то для него время по сути «прыгнет» назад (59.00, 59.25, 59.50, 59.75, 59.00). Поэтому если выполняемая операция сильно зависит от этого времени, нужно учесть такой вариант развития событий.
Перевод совершенно ручной. За стилем не гнался, главное «месседж».
Я не в обиду, если что. Просто некоторые фразы уж очень режут глаз ("...UTC держится в не более чем 0,9 секунды от физической реальности...", «Это представляет собой проблему...»), поэтому и возникло впечатление машинного перевода с ручной правкой.
В любом случае спасибо за перевод и за то, что обратили внимание на эту статью, весьма полезный сборник фактов и советов без лишней «воды».
>>Когда измеряете время, измеряйте Unix-время

а как быть если нужны миллисекунды?
Немного фантастики:

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

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

Артур Кларк, «3001: последняя одиссея»
возможно, сегодняшние айтишники предложили бы более радикальное исправление земной орбиты — 8 или 16 месяцев по 32 дня (четыре восьмидневных недели) =)
Окститесь! Ни один айтишник не согласится променять семидневку на восьмидневку!
а если будет две пятницы?
Тогда разные придурки мне будут присылать вдвое больше дебильных картинок с котами.
Обычно в пятницу другого рода картинки присылают…
помню у Винджа в цикле «Кенг Хо» не было ни часов, ни дней ни месяцев ни лет. Все меряли в секундах, килосекундах, мегасекундах.

И в тексте книги только такие обозначения: «отдохнул пару килосекунд», «в течение следующих 5 мегасекунд» и т.п.

По началу раздражает, сидишь и пересчитываешь в уме, потом привыкаешь.
С точки зрения хранения да, UTC обычно хватает. А вот для решения всяких расчетных проблем, связанных с временем, без time zones не обойтись никак. На ХаккерНьюс предложили такой пример:

«Мы проводим еженедельный митинг каждый понедельник в 9 утра в Сан-Франциско. Вы сейчас в Лондоне и хотите присоединиться к митингу по Скайпу. Во сколько вы должны его включить?

7 марта 2011 — в 5 вечера
14 марта 2011 — в 6 вечера
29 марта 2011 — в 5 вечера

Чтобы рассчитать все это, требуется знать о правилах перехода на летнее время и о таймзонах в регионах участников»

Кроме того, строго говоря, проблема таймзон до сих пор не решена полностью. Сегодня большинство использует один источник правил работы с таймзонами — tzdata en.wikipedia.org/wiki/Tz_database
К сожалению, он не без багов. Например, Томская область долгое время значилась в зоне Новосибирска, хотя и перешла из одного пояса в другой в 2002 году. Обнаружили проблему только в 2008. Сейчас этот баг неактуален в связи с всеобщем сокращением поясов, но в случае с работой данными нескольких лет давности следует иметь его ввиду. Вполне вероятно, что подобный случай неединичен.
Время проходит со скоростью одну секунду за секунду для всех наблюдателей. Частота удалённых часов по отношению к наблюдателю зависит от скорости и гравитации. Часы внутри спутников GPS регулируются для преодоления эффектов относительности.

Можно об этом по-подробнее?
поподробнее лучше к Хокингу
UFO just landed and posted this here
Спасибо, К.О.

Конечно же имелось ввиду на какие величины и как часто регулируются часы для преодоления эффектов относительности. А также примерные расчёты показывающие это.
«Also, the orbiting clocks are 20,000 km above the Earth, and experience gravity that is four times weaker than that on the ground. Einstein's general relativity theory says that gravity curves space and time, resulting in a tendency for the orbiting clocks to tick slightly faster, by about 45 microseconds per day. The net result is that time on a GPS satellite clock advances faster than a clock on the ground by about 38 microseconds per day.» www.physicscentral.com/explore/writers/will.cfm
И главного так и не сказано:
— Что должен знать о времени каждый программист?
— Никогда не храни часовой пояс точки в виде смещения от Гринвича.
Так, а если я буду замерять время (например, исполнения кода), а в это время Unix-time перескакнёт вперёд/назад из-за високосной секунды?
MySQL хранит столбцы типа DATETIME в виде упакованных в числа значений «YYYYMMDD HHMMSS»

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

Более того, к глубокому сожалению, приходилось встречаться с такими «специалистами по юзабилити», которые вообще не берут в голову не только часовые пояса или переход на летнее время, но даже форматы дат и времени.
Чтобы лучше осознать, стоит ли вообще помнить про такую «мелочь», как летнее время, рекомендую посмотреть на карту в статье http://en.wikipedia.org/wiki/Daylight_saving_time (какие страны переходят на летнее время).
Когда отображаете время, всегда включайте в него смещение часового пояса. Формат времени без смещения бесполезен.

Весьма спорное утверждение. Пожалуй верно, если речь идет об отображении времени в лог-файлах.
В остальных случаях часовой пояс быстро намозолит глаза, если отображать его без особой необходимости. Время без часового пояса — это время по некоторому соглашению в данном контексте.
Мало того, неподготовленного пользователя часовой пояс в виде +0400 ещё и сбивает с толку. Как перейти от 12:00 +1200 к местному (+0400 например) ему непонятно. То ли +1200 это обзначение аналогичное "(Камч. вр.)" и ему нужно вычесть 8, то ли вычесть 12 и прибавить 4, то ли просто прибавить 4, то ли ещё что.

В подавляющем большинстве случаев пользователю нужен только один контекст — его местное время. В подавляющем большинстве остальных случаев — какое-то общее время с другими пользователями приложения распределенного приложения — UTC, московское, ETC/EDT по которому он сам может вычислить местное и наоборот.
Я когда служил в ВС, меня не сказанно удивила наш кадровик, которая высчитывала выслугу лет.
Оказывается, очень легко на бумажке посчитать сколько прошло времени (выслуга) между двумя датами, например
23 мая 1985 года и 12 февраля 2010 года.

Способ настолько простой, что хочу поделиться им со всеми.
Оказывается, все надо высчитывать в стобик.
2010/02/12
-
1985/05/23


По умолчанию берем, что в месяце 30 дней. Далее по арифметическим правилам вычитания. Т.к. 12 меньше 23, берем 30 дней из 02 месяца (февраль = январь + 30 дней), получаем

2010/01/(30+12)
-
1985/05/23


Тоже самое с годами. В году 12 месяцев. Т.к. 01 меньше 05, то берем 12 месяцев из 2010 года (остается 2009)

2009/(12 +01)/(30+12)
-
1985/05/23


и вычитаем:
2009/(12 +01)/(30+12)
-
1985/05/23
= 
24 года /08 месяцев /19 дней


И получаем, что с момента 1985/05/23 до 2010/02/12 прошло 24 года 8 месяцев и 19 дней.
Данный способ независим от количества дней в месяце и высокосных лет.

посчитал в программе, говорит 24 года, 8 месяцев и 10 дней.


var
  d1, d2: TDateTime;
begin
  d1 := StrToDate('23.05.1985');
  d2 := StrToDate('12.02.2010');

  ShowMessage( IntToStr(YearsBetween(d2, d1)) + ' ' 
                        + IntToStr(MonthsBetween(d2, d1) mod 12)  + ' ' 
                        + IntToStr(DaysBetween(d2, d1) mod 31))

Тут все дело в понятиях.

Например. Сегодня 6 июля.
Какое число было месяц назад? А два месяца назад? А год назад?
Мы знаем, что всегда получится 6 число.

А с математической точки зрения — ответ будет разным. Ведь в месяце может быть 28-31 день. А в году 365-366 дней.

Так что, с математической точки зрения, месяц назад — это может быть 4,5,6,7 числа, в зависимости от того, какой месяц имеется ввиду.

Так же получилось и у вас. С математической точки зрения (с учетом високосных лет и разницы в длине месяца) может быть и правильно.
Но, не знаю какое подобрать слово, восприятия что ли, получается неправильно.
Проверить просто — к дате 1985-05-23 прибавить 10 дней — результатом никак не будет 12 число (исходная дата 2010-02-12).
Да, я понял о чем вы говорите. Дело действительно в том, что «месяц назад» или «год назад» — условная и неточная формулировка
Нуда.
Но, она часто применятся как в жизни (ребенку 2 года, 3 месяца и 6 дней)
так и в интернетах (владелец анкеты последний раз был на сайте 2 месяца и 18 дней назад).
ГК РФ с вами не согласен
Статья 192. Окончание срока, определенного периодом времени
1. Срок, исчисляемый годами, истекает в соответствующие месяц и число последнего года срока.
К сроку, определенному в полгода, применяются правила для сроков, исчисляемых месяцами.
2. К сроку, исчисляемому кварталами года, применяются правила для сроков, исчисляемых месяцами. При этом квартал считается равным трем месяцам, а отсчет кварталов ведется с начала года.
3. Срок, исчисляемый месяцами, истекает в соответствующее число последнего месяца срока.
Срок, определенный в полмесяца, рассматривается как срок, исчисляемый днями, и считается равным пятнадцати дням.
Если окончание срока, исчисляемого месяцами, приходится на такой месяц, в котором нет соответствующего числа, то срок истекает в последний день этого месяца.
4. Срок, исчисляемый неделями, истекает в соответствующий день последней недели срока.
Все эти понятия подразумевают не только «Срок», но и дату с которой он начался.

Просто срок — 24 года, 8 месяцев и 19 дней — понятие не точное без привязки к календарю
Точное, но относительное :)
Хохо…
Буквально в этом месяце добавляли поддержку временых зон в крупный питоний проект. Очень выручили питоний мудуль pytz в комплекте с datetime и кастомное поле для SQLAlchemy которое сыпет варнинги на попытку передать ему время с непроставленной временной зоной.
Но вообще опыт очень интересный вышел — столько кода пришлось править…
Вывод: поддержку временных зон нужно вводить с самого начала разработки проекта.
> Время проходит со скоростью одну секунду за секунду для всех наблюдателей.

По-моему, должно быть как раз наоборот — время НЕ проходит со скоростью 1 секунда в секунду для всех наблюдателей. Время идёт по-разному в разных системах отсчёта.
Sign up to leave a comment.

Articles