Как библиотеки на разных языках программирования обрабатывают дату и время, метки времени и длительности, секунды и годы, летнее время и часовые пояса, ...? - PullRequest
22 голосов
/ 14 сентября 2010

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

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

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

Ответы [ 6 ]

17 голосов
/ 14 сентября 2010

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

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

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

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

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

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

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

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

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

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

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

Интеграция

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

Ссылки:

11 голосов

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

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

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

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

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

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

ОСНОВНАЯ ПРОБЛЕМА со всеми библиотеками даты / времени во всех системах, фреймворки таковы, что их типы данных даты / времени не позволяют включать географическую и календарную информацию в типы данных даты / времени .
Без чего они в основном наполовину бесполезны - какой смысл в миллисекундах в значениях datetime2 SQL Server в 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! = C # DateTime.MinValue, почему?
SqlDateTime.MinValue! = DateTime.MinValue, почему?

* 1 072 * [4]
InteНациональная организация по стандартизации
http://en.wikipedia.org/wiki/International_Organization_for_Standardization
[4a] ISO 8601 Элементы данных и форматы обмена. Обмен информацией. Представление даты и времени
http://en.wikipedia.org/wiki/ISO_8601 * * Тысяча восемьдесят-одна [5] * * 1 082 Григорианский календарь
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] * * 1 092 http://en.wikipedia.org/wiki/Galileo_Galilei
10 голосов
/ 15 сентября 2010

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

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

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

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

7 голосов
/ 09 октября 2010

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

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

Boost Date Time

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

Мотивация

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

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

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

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

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

Расчеты

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

Ограничения

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

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

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

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

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

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

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

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

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

Это полностью поддерживается и является одной из сильных сторон библиотеки из-за соответствующей мощности базовой системы ввода / вывода C ++, см. Date Time Input / Output - потоково-ориентированный C ++ I / Oимеет свои достоинства и проблемы в зависимости от ваших потребностей и ожиданий, но эта тема обсуждается в другом месте на этом сайте.

Интеграция

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

4 голосов
/ 16 октября 2010

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

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

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

4 голосов
/ 05 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...