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

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

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

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

Ответ 1

Я попытаюсь дать ответ на второй и третий вопрос, используя библиотеку 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, которые позволяют людям точно выбирать, какое определение времени они нуждаются. I. е. "дневной", "линейный, без прыжковых секунд" и т.д.

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

Работа с данными о часовом поясе и DST

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

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

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

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

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

Интеграция

  • Базы данных
  • JodaTime
  • Классы Legacy JDK (java.util.*)
  • XML

Литература:

Ответ 2

Есть время и есть даты (календари)
Первая проблема заключается в том, что даты не связаны со временем, а с астрономическим положением 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 (или откройте панель управления → Дата и время) → вкладка Часовой пояс → просмотрите часовые пояса в поле со списком. Вы увидите, что есть 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!= С# 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

Ответ 3

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

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

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

Надеюсь, это ответ на ваш вопрос в отношении ICU.

Ответ 4

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

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

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

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

Мотивация

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

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

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

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

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

Вычисления

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

Ограничения

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

Работа с данными часового пояса и DST

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

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

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

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

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

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

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

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

Интеграция

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

Ответ 5

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

Ответ 6

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

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

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