Как библиотеки на разных языках программирования обрабатывают Date & Time, Timestamps & Durations, Leapseconds & -ears, DSTs & Timezones, …?

Существует ли стандартный орган или конкретный нормативный способ, как на практике должны выполняться связанные с временем вещи (например, ICU для задач, связанных с Unicode), или это в настоящее время является «наилучшим усилием», в зависимости от того, сколько усилий, времени и денег и библиотекаторы хотят потратить?

Существует ли конкретная и полная реализация, которая может служить примером того, как нужно обрабатывать связанные с временем вещи?

Какую существующую библиотеку вы считаете плохим, достойным или хорошим примером?

Я попытаюсь дать ответ на второй и третий вопрос, используя библиотеку Java, которая может стать частью Java 7.

javax.time. * (JSR 310)

Эти классы – полная переработка JodaTime, которая пытается исправить недостатки дизайна util.Date / util.Time а также JodaTime.

JSR 310 пытается предоставить всеобъемлющую модель для даты и времени, которая является безопасной и самодокументированной. Он совместим с существующими классами, но также рассматривает варианты использования на основе XML и СУБД. Классы являются окончательными, неизменяемыми, потокобезопасными и не могут быть изменены после строительства. Экземпляры создаются с помощью богатого набора методов Factory, которые могут кэшировать вещи в фоновом режиме.

 LocalDate dateToday = LocalDate.of(2010, 9, 14); LocalDate oneMonthLater = dateToday.with(OCTOBER); LocalDate oneYearLater = dateToday.withYear(2011); 

API имеет некоторые «машиностно-ориентированные» классы и некоторые «ориентированные на человека» классы:

Машинно-ориентированные

Instant

В течение некоторого времени, сопоставимого с отметкой времени Unix или Java. На самом деле есть Instant , TAIInstant и UTCInstant которые позволяют людям точно выбирать, какое определение времени они нуждаются, т.е. «дневные», «линейные, без скачков» и т. Д.

Duration

Диапазон времени не обязательно связан с конкретной датой или календарем.

Человек-ориентированный

Существует богатая коллекция классов, обрабатывающих различные варианты использования, такие как Date-only, Time-only, Time and Date, с часами и без них, с и без DST.

DateProvider

OffsetDate , LocalDate (, совместимость с java.sql.Date )

TimeProvider

OffsetTime , LocalTime (, совместимость с java.sql.Time )

DateTimeProvider

ZonedDateTime , OffsetDateTime , LocalDateTime (, совместимость с java.util.GregorianCalendar )

InstantProvider

Instant , ZonedDateTime , OffsetDateTime (, совместимость с java.util.Date )

Period

Периоды представляют собой временной интервал типа «5 дней», который можно добавить и вычесть из даты / времени.

Matcher

Матчи включают такие запросы, как «эта дата в 2006 году?» или «в этот день последний день этого года».

Adjuster

Настройщики приходят на помощь, если вы хотите сделать более сложные изменения, такие как «Дайте мне последний день месяца!» или «Второй вторник после Рождества, пожалуйста!».

Resolver

Резольверы позволяют пользователям определять, что должно произойти, если определенная дата недействительна, например, 31 февраля 2010 года:

 DateResolver previous = DateResolvers.previousValid(); LocalDate date = date(2010, 2, 30, previous); // date = 2010-02-28 

Работа с данными Timezone и DST

Можно сериализовать эти классы и десериализовать их, используя либо данные текущего часового пояса, либо данные о часовом поясе, когда они были сериализованы. Кроме того, можно сравнивать правила разных часовых поясов: можно узнать, изменились ли правила DST, например, между версией 2010e и 2010f для дат в Лондоне или Москве и решить, что делать, если время находится в промежутке или перекрывается.

Календарные системы

Несмотря на то, что все основано на ISO-8601 , предоставляются простые календари для иврита, хиджры, японского, тайскогоBuddist и т. Д.

Форматирование и анализ

toString() возвращает ISO8601, а шаблоны, подобные тем, что указаны в SimpleDateFormat , поддерживаются более продвинутыми.

интеграция

  • Базы данных
  • JodaTime
  • Наследственные классы JDK ( java.util.* )
  • XML

Рекомендации:

Есть время (ы) и есть даты (календари)
Первая проблема заключается в том, что даты не связаны со временем, а с астрономическим положением Earh, Moon и т. Д. + Регулярность / периодичность человеческой деятельности. Время также субъективно и относительное или даже релятивистское и измерено либо астрономически, либо атомарно.

Органы времени и органы даты / календаря
Международная организация по стандартизации (ИСО) [4] издала

  • «ISO 8601 Элементы данных и форматы обмена – Обмен информацией – Представление дат и времени» [4a]

которая, как и другие международные стандарты, является рекомендацией и основана на уже сложившейся практике.
Он (субъективно) основан только на Григорианском календаре [5] и на пролептическом (проецируемом назад до того, как он был фактически изобретен, поэтому имеет ограниченное применение при работе с историческими датами) [5а].

Всемирная ассоциация календаря [1d] инициировала введение нового Всемирного календаря с 2012 года [1b-1d], который создал бы бесполезные уже существующие библиотеки дат. Опять же, та же самая основная проблема, см. Дальше.

Наибольшее покрытие, которое я когда-либо видел, сопоставило дату и время в ИТ-системах [2] между СУБД BIG8 (IBM DB2, Informix, Ingres, InterBase, Microsoft SQL Server, MySQL, Oracle и Sybase).
Это и все другие опросы показывают, что обработка того же самого, например, по времени или датах в григорианском календаре, различна для всех систем, а также внутри одной и той же платформы (между различными продуктами и версиями одного и того же продукта), см., Например, , [3].

ОСНОВНАЯ ПРОБЛЕМА со всеми библиотеками времени и времени во всех системах – это то, что их типы данных даты / времени не позволяют включать географическую и календарную информацию в типы данных даты / времени .
Без чего они в основном бесполезны – каков смысл миллисекунд в значениях SQL Server datetime2 в 7 веке? В то время даже часы не измеряли время с точностью до минут (Галилей Галилей использовал, например, его сердце бьется, чтобы измерять интервалы времени в своих экспериментах), а также григорианский календарь даже не был изобретен.

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

Просто быстрые иллюстрации:

  • Современная Россия использует григорианский календарь, а Русская православная церковь использует юлианский календарь, на котором определяются многие государственные праздники в России (например, Рождество в России – 7 января, а Новый год – 14 января по григорианскому календарю, а даты другие религиозные праздники плавают относительно Григорианского календаря).
  • В до 1917 г. Россия, Польша в качестве своей части, использовала Григорианский календарь, а остальная Россия использовала Юлианский календарь (с плавающей разницей 13-18 дней в «тот же» часовой пояс) [5b];
  • Дважды щелкните часы в MS Windows (или откройте Панель управления -> Дата и время) -> вкладка Часовой пояс -> просмотрите часовые пояса в combobox. Вы увидите, что есть 25 часов с GMT-12: 00 до GMT + 13: 00 более ста часовых поясов с долями часа, как GMT + 5: 00, GMT + 5: 30, GMT + 5: 45 и т. Д. ,

==== Цитируется:
[1] Новый календарь
[1a] Обновление: Извините, не читайте [1a], автор путал календари и написал неправильную информацию в этой новостной записке
Всемирный календарь 2012: 35 дней в месяц
http://www.panorama.am/en/society/2010/01/29/newcalendar
[1b] http://en.wikipedia.org/wiki/World_Calendar
[1c] http://www.theworldcalendarin2012.org/Index2.htm
[1d] http://www.theworldcalendar.org/TWCA.htm

[2] Питер Гулуцан, Труди Пельцер. Настройка производительности SQL: Даты в SQL
http://www.informit.com/articles/printerfriendly.aspx?p=30939

[3] SqlDateTime.MinValue! = C # DateTime.MinValue, почему?
SqlDateTime.MinValue! = DateTime.MinValue, почему?

[4]
Международная Организация Стандартизации
http://en.wikipedia.org/wiki/International_Organization_for_Standardization
[4a] ISO 8601 Элементы данных и форматы обмена – Обмен информацией – представление дат и времени
http://en.wikipedia.org/wiki/ISO_8601

[5]
Григорианский календарь
http://en.wikipedia.org/wiki/Gregorian_calendar
[5a] Пролепический григорианский календарь
http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
[5b] Принятие Григорианского календаря
http://en.wikipedia.org/wiki/Gregorian_calendar#Adoption
[6]
http://en.wikipedia.org/wiki/Galileo_Galilei

Я не думаю, что на данный момент существует один стандарт для таких вещей, однако есть несколько стандартов, которые могут соответствовать таким требованиям: например, ISO 8601.

Собственная дата / время работы ICU – это многоязычная (C / C ++ и Java) и многоплатформенная библиотека.

Он обрабатывает даты и время внутри, как правило, используя для одного времени UDate (C / C ++) или java.util.Date/long (Java), как количество миллисекунд с 1 по 1970 год, или объект Calendar, который специфичен для типа календаря (григорианский против хиджри и т. д.). Для форматирования доступны длительности. Високосные годы рассчитываются как часть календарных систем, и считается, что скачки секунд обрабатываются базовой операционной системой. Данные DST / Timezone сохраняются в актуальном состоянии с помощью «базы данных tz», иногда упоминаемой ее фамилией автора, Олсоном.

Надеюсь, это ответили на ваш вопрос в отношении ОИТ.

Я не использовал его некоторое время, но из прошлого опыта я бы сказал, что Boost.Date_Time – довольно хороший пример.

Хотя, вероятно, это не первый выбор для многих быстрых проектов сегодня, выразительная сила C ++ по-прежнему кажется очень хорошим совпадением для сложного проблемного домена, такого как дата / время, поэтому в сочетании с высококачественным процессом экспертной оценки, чтобы пройти, чтобы стать официальная библиотека Boost C ++. Я надеюсь, что библиотека под рукой может служить примером того, как обрабатывать связанные с временем вещи , хотя и не как полную реализацию , см. ниже.

Время увеличения времени

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

мотивация

Мотивация для этой библиотеки связана с работой и поддержкой нескольких библиотек времени для нескольких проектов. […]

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

Концепции доменов

Библиотека поддерживает 3 основных временных типа:

  • Time Point – спецификатор для местоположения в континууме времени.
  • Time Duration – Длительность времени, не привязанная к какой-либо точке континуума времени.
  • Интервал времени – длительность времени, привязанного к определенной точке временного континуума. Также известен как период времени.

вычисления

Вы можете получить довольно интуитивный обзор того, как концепции домена связаны друг с другом в разделе « Детали – вычисления» .

Ограничения

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

  • Цели проектирования
  • Компромиссы: стабильность, предсказуемость и приближения

Работа с данными Timezone и DST

Существует полная поддержка всех видов вычислений и конверсий, о которых можно подумать, насколько мне известно – см. Заголовки в разделе Примеры для первоначального впечатления.

Календарь / Системы времени

Это, безусловно, слабое место в отношении вашей спецификации, несмотря на то, что библиотека специально разработана с учетом расширяемости:

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

Тем не менее, я не знаю о каких-либо реализациях других систем календаря и времени, кроме тех, которые включены, см. Ссылку на библиотеку для текущих реализаций:

  • Дата Время
  • григорианский
  • Время Posix
  • Местное время

Форматирование и анализ

Это полностью поддерживается и является одной из сильных сторон библиотеки из-за соответствующей мощности базовой системы ввода-вывода C ++, см. «Ввод / вывод даты времени» – поточно-ориентированный ввод-вывод C ++ имеет как достоинства, так и проблемы в зависимости от ваших потребностей и ожидания, но эта тема обсуждается в другом месте на этом сайте.

интеграция

Это обеспечивается также благодаря совместимости с Boost Serialization , которая ориентирована на архив, хотя обычно это означает файл двоичных данных, текстовые данные, XML или так; т.е. базы данных явно не поддерживаются, как в вашем примере JSR 310 .

Вы упоминаете Python в более раннем комментарии.

Поддержка встроенного datetime в формате Python (docs) довольно практична, но вы должны использовать стороннюю базу данных часовых pytz такую ​​как pytz (docs), чтобы закрыть ее. И, как упоминает pytz docs, у вас все еще могут быть проблемы с добавлением дельт к временам прямо перед переходами DST, если вы не будете осторожны.

Когда-то было так, что mx.DateTime eGenix был способом, если datetime не сделал этого для вашего приложения, особенно для преобразования строк в timestamp, но dateutil, похоже, популярен в эти дни (я его еще не использовал) ,

Чтобы ответить на ваш вопрос «Хороший пример», взгляните на Noda Time – порт Jon Skeet для библиотек Joda-Time для Java на .Net