Почему нет настоящего типа данных «Только для даты»?


24

Я так смешно разочарован необходимостью использовать значения DateTime для наборов данных, которые действительно "всего лишь день". Дни рождения - самый распространенный пример, но это постоянно встречается в бизнес-приложениях.

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

Время всегда относительно фиксированной точки. 4 вечера - 4 часа после меридиана или полдень. Наблюдается самая высокая точка Солнца в пути, что позволяет нам установить систему координат. За 3 часа до полудня (Анте Меридиан), через 2 часа после полудня, 1441899402938 миллисекунд с 1 января 1970 года. Для людей, выросших в декартовом мире, это вторая натура.

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

Аналогично с повторением лет. Каждые 365 дней (или около того) у меня есть несколько особых дней: дни рождения, юбилеи, дни рождения детей и т. Д. мы МОЖЕМ отобразить это на число с плавающей запятой, и, по правде говоря, отображение его на указанное число решает ОЧЕНЬ много проблем, которые действительно сложны по-старому, но это не значит, что это единственный способ сделать это.

Понимание и понимание природы «квадратного колышка в круглой дыре» использования DateTimes для хранения дат делает, по моему мнению, лучшим программистом.

Есть ли смысл в приложении, явно предназначенном для планирования, при определении класса Date или «лучший способ установить полдень»? Какие проблемы могут возникнуть при использовании DateTime и установке компонента Time в полдень? Можно ли учитывать изменение часового пояса при таком подходе? Я использовал MomentJS, но я думаю, что это просто лучший класс Date.


7
это довольно интересный вопрос, я думаю. Возьмите пример дня рождения, это действительно имеет смысл только для человека, я живу в одном месте, и все просыпаются в одно и то же время. как только вам нужно выразить это математически, это становится очень сложным. То же самое с вещами , как работа сдвиг начала / конца времен и т.д. они Арент «раз» они «часов дня в часовом поясе , в котором вы работаете»
Ewan

3
NodaTime (библиотека C # для даты и времени) имеет тип дат.
CodesInChaos,

5
Сохраняйте время как UTC, без проблем с датой, без часовых поясов.
Лорен Печтел

3
«Но, боже, это похоже на хак, и я навсегда нахожу ошибки от младших разработчиков, которые путешествуют по этой проблеме». - почему бы вам просто не создать свой собственный класс DateOnly или что-то еще и назвать его днем.
Брандин

5
@MichaelBlackburn Я серьезно. Ваше объяснение звучит точно так же для ситуации с собственным типом данных, который применяет бизнес-правило (только дата, например, вы можете хранить его как «DateTime» внутри с частью времени, установленной в полдень), но затем выставлять только те части, которые вам нужны (месяц , день и т. д. год / не год).
Брандин

Ответы:


15

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

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

Позвольте мне кратко упомянуть, что это неправда, что все языки программирования предлагают только временные типы данных, которые включают компонент времени. Я встречал типы данных только для дат в СУБД и на соответствующих им диалектах SQL. Но это не имеет значения: тот факт, что эти типы данных существуют, не означает, что они полезны, и СУБД имеют долгую историю путаницы хранения с представлением.

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

Например, в DateTimeтипе данных Microsoft Dotnet единица времени составляет 100 наносекунд, а начало времени - 12:00 ночи, 1 января, 0001 г.

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

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

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

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


4
Это не относится к «Дням», которые являются концепцией даже старше, чем Время. Они наиболее правильно считаются перечислением или модулем. Воскресенье следует за понедельником и т. Д., Пока мы не вернемся к воскресенью, которое следует за субботой. Это действительно другое.
Майкл Блэкберн

10
Ну, конечно, в больнице записано время рождения - это стандартная практика в большинстве больниц. Это не проблема вообще. Проблема заключается в том, что в целях празднования событий (дни рождения, праздники, юбилеи и т. Д.) Люди не используют или не хотят получить разрешение более 1 дня. Спросите первого человека, которого вы видите, когда у них день рождения, и он даст вам месяц и день, но не час и минуту. Кроме того: мы используем единицы измерения, которые постоянно включают масштаб: миллиметр, килограмм, мегаватт и, действительно, микрофарад.
Калеб

4
-1: не все виды использования времени должны представлять один момент времени. День рождения - это другая идея, представленная месяцем и днем ​​в григорианском календаре. Имеет смысл спросить "у Кевина сегодня день рождения?" Ответ зависит от местоположения. Если бы я был в Сиднее, это мог бы быть мой день рождения, но если бы я был в Гонолулу, это не было бы в течение нескольких часов.
Кевин Клайн

6
@MikeNakis Результат будет микроампер, а не чепуха. Более важно: когда вы используете дату, а не секунду или миллисекунду, вы обычно говорите о целом дне - периоде времени, а не о конкретном времени, и в зависимости от контекста это может быть повторяющимся событием.
Калеб

4
ОП говорила о днях рождения, которые точно представлены java.util.MonthDay. День рождения - это не измерение, это человеческое представление о дне, которое повторяется ежегодно. Есть много человеческих представлений о времени, которые не представлены ни одним моментом времени.
Кевин Клайн

9

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

DateTimeТипа присутствует во многих языках представляют собой точную точку во времени ( «мгновенное время»). Помимо этого у нас есть ряд относительных или «человеческих» концепций времени и времени, таких как календарные дни, повторяющиеся даты, месяцы, годы и т. Д., Которые во многих случаях неоднозначны и зависят от контекста. Эти типы не так универсально полезны, но необходимы в определенных областях приложений, таких как календари, инструменты планирования и другие приложения, которые взаимодействуют с человеческими представлениями о времени.

Если вы пишете что-то наподобие календарного приложения, вы определенно выиграете от использования библиотеки, такой как Joda-time, которая предоставляет более богатый набор типов времени. Например LocalDate, дата без времени. Это имеет семантику, отличную от обычной DateTimeс временной частью, установленной на ноль, так как по- DateTimeпрежнему указывает конкретный момент времени (полночь в определенном часовом поясе), в то время какLocalDate указывает на весь день и не привязан к конкретному часовому поясу. Это также означает, что вы не можете напрямую перевести одно на другое.

LocalDate конечно проще чем DateTime потому, что не нужно принимать во внимание часовые пояса, но вы должны знать о других проблемах, например, о том, что текущая дата может фактически измениться, когда вы пересекаете часовой пояс, и что тот же самый момент времени может соответствуют разным датам в разных часовых поясах. Если вы используете локальные даты в сетевых или веб-приложениях, вы должны быть очень осторожны с этими проблемами. Удаление временной части из даты не решает фундаментальную проблему часовых поясов! И если принять во внимание исторические даты и различные культуры, это станет еще сложнее, поскольку одна и та же дата может соответствовать совершенно разным моментам времени, скажем, в юлианском и григорианском календарях.

Теперь вы спрашиваете, почему у языков нет чего-то подобного LocalDate встроенному . Ну, во-первых, некоторые языки, такие как SQL и Visual Basic, имеют тип даты без временной части. И Java также добавили LocalDateв недавней версии. Но других платформ, таких как .Net нет. Только разработчики языка могут действительно ответить, почему это не включено в стандартную библиотеку, но я предполагаю, что «мгновенное время» концептуально просто и универсально полезно, в то время как другие понятия времени полезны только для конкретных областей применения (таких как календари и т. Д.). .). Поэтому имеет смысл позволить разработчику приложения написать собственные типы для обработки более сложных вариантов использования или разрешить его обработку сторонней библиотекой (например, Joda-time).


5

Я так смешно разочарован необходимостью использовать значения DateTime для наборов данных, которые действительно "всего лишь день". Дни рождения - самый распространенный пример, но это постоянно встречается в бизнес-приложениях.

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

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

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

Все эти факты процитированы из превосходного FAQ, найденного в календарной библиотеке для OCaml, написанной Жюльеном Синьоль.

  1. Юлианский календарь был введен Юлием Цезарем в 45 году до нашей эры. Он использовался до 1500-х годов, когда страны начали переходить на григорианский календарь (раздел 2.2). Однако некоторые страны (например, Греция и Россия) использовали его в 1900-х годах, и православная церковь в России все еще использует его, как и некоторые другие православные церкви.

  2. Переход от юлианского к григорианскому календарю происходил неравномерно, и в зависимости от года изменения было упущено от 10 до 13 дней. Например, во Франции 9 декабря 1582 г. последовало 20 декабря 1582 г., а в Греции 9 марта 1924 г. - 23 марта 1924 г.

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

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

  1. Доли в годах (например, «6 месяцев» соответствуют «0,5»), которые используются в сочетании с процентной ставкой для расчета фактической процентной ставки по кредиту за определенный срок. Существует 6–10 рецептов для вычисления этих фракций, каждый из которых отличается по способам обработки продолжительности високосного года, позиции периода относительно последнего дня февраля и продолжительности месяца.

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

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

Есть ли смысл в приложении, явно предназначенном для планирования, при определении класса Date или «лучший способ установить полдень»? Какие проблемы могут возникнуть при использовании DateTime и установке компонента Time в полдень? Можно ли учитывать изменение часового пояса при таком подходе? Я использовал MomentJS, но я думаю, что это просто лучший класс Date.

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


2

Я думаю, что Майк Накис в своем ответе выше лучше объясняет, как время в целом является абсолютной измеренной координатой, а любая другая связь, предполагаемое состояние или постоянство этой временной координаты - просто абстрактное представление указанной временной координаты.

Вы говорите с такими представлениями, когда называете День недели просто модульным представлением фактического момента времени. На самом деле это несколько сложнее, чем это. Если вам было поручено написать функцию, которая будет возвращать день недели для данного момента времени, рассмотрите следующую информацию, которая вам понадобится в качестве входных данных для такого алгоритма. Вам потребуется момент времени, календарь, часовой пояс, который необходимо учитывать (имейте в виду, что часовые пояса меняются ВСЕ ВРЕМЯ, поэтому вам нужно знать, когда этот эффективный часовой пояс начал существовать, когда он заканчивался в определенных временных координатах. Недавно Северная Корея просто например, изменили их!), и если действует летнее время, оно также меняется со временем. Теперь рассмотрим, если вам дали DateTime в местном часовом поясе,

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

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

Время действительно является координатой, но помимо простой даты, рассмотрим другие чувствительные ко времени данные, которые могут понадобиться, например:

Длительность: промежуток в миллисекундах, который может произойти, что означает длительность или протекание времени без указания конкретных временных координат. Вариант использования может быть,

Как пользователь, я хотел бы, чтобы эта задача выполнялась через 15 секунд после завершения полуночной работы каждую среду.

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

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

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

Итак, в заключение, вся эта информация неизбежно приводит к следующим соображениям дизайна:

  • Определенные точки или диапазоны во времени должны сохраняться в UTC или некотором типе данных, который содержит достаточно информации, чтобы ее можно было легко абстрагировать обратно в UTC, где это необходимо.
  • Логика приложения должна быть написана для форматирования UTC или диапазона координат UTC в состояние представительных данных, которое является более удобочитаемым для конечного пользователя.
  • Важные длительности должны сохраняться в миллисекундах
  • Конкретные региональные настройки или предпочтения конечного пользователя при отображении любых данных, касающихся времени, должны сохраняться как дополнительные данные и рассматриваться как опция отображения. (Например, киоск A, центральный часовой пояс, формат военного времени или пользовательские настройки B, стандартное время в Тель-Авиве (GMT + 7: 00), часовой пояс и т. Д.)
  • Избегайте номеров FP

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

1
@AlanShutko И да, необходимы «дополнительные данные», такие как местный часовой пояс, дни и любые другие важные данные, которые должны быть получены. Однако это всего лишь абстракции в определенный момент времени, даже если момент времени не важен для вашего алгоритма. Что касается наносекундного и даже микросекундного масштаба, мой ответ больше ориентирован на веб-приложения и ПО типа LOB. Я сомневаюсь, что выбранный язык LHC - C # или Javascript.
maple_shaft

1
Миллисекунды отлично подходят для повторяющихся физических процессов. Для человеческой деятельности иногда подходящей единицей являются номинальные дни, например, если она отправлена ​​в конце дня, она будет доступна для использования в пункте назначения через три дня.
Кевин Клайн

В прошлом я рассматривал использование 64-битных чисел с плавающей запятой для временных координат, и что более важно для временных интервалов, поскольку они позволяют вам выражать крошечные величины с большой точностью, а также огромные величины, где потеря точности не имеет большого значения , (Так что, если Динозавры умерли 65 миллионов лет назад, дать или занять несколько лет?) Итак, почему вы говорите, что их следует избегать?
Майк Накис

Майк, я думаю, его беспокоит то, что математика FP неизбежно округляется, поскольку она конвертирует из десятичных в двоичные значения. Например, 0,3 является повторяющимся десятичным числом, если оно выражено в виде двоичного числа FP, и поэтому не может быть точно представлено. Дело не в том, что вам не хватает пропускной способности, но вам не хватает точности.
Майкл Блэкберн

2

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

Есть 2 крайних случая, которые не поддаются обычному подходу. Установка момента времени, который находится на другой стороне перехода на летнее время, с использованием местного времени, которое затем преобразуется в UTC более низким уровнем абстракции, а затем на 1 час раньше или позже для вашей встречи.

Другой (в соответствии с вопросом) моделирует произвольную информацию о дате, такую ​​как запись даты рождения человека. Представьте себе случай, когда два человека родились одновременно, один в Новой Зеландии, другой на Гавайях. Вероятно, что в их паспортах будут разные даты рождения, и если человек, родившийся на Гавайях, переедет в Новую Зеландию, он будет считаться на день старше, чем человек, родившийся в Новой Зеландии, несмотря на то, что он прожил в то же время.

Предложение в вопросе, как установить дату, чтобы иметь время полудня, UTC будет работать, ПОЧТИ везде. Смещения UTC варьируются от -12 до +14, поэтому в Тихом океане есть несколько мест, где этот подход потерпит неудачу. Я склонен относиться к этим типам данных как к строкам в формате ггггммдд, и если мне нужно сравнить вычисления между двумя датами, это можно безопасно сделать как сравнение строк. При выполнении дельта-сравнений (например, между датой и временем или продолжительностью до достижения возраста X) необходимо убедиться, что все даты созданы с одним и тем же смещением UTC, а затем использовать стандартные функции времени для выполнения работы.


3
« Я склонен относиться к этим типам данных как к строкам в формате ггггммдд, и если мне придется сравнивать вычисления между двумя датами, это можно безопасно сделать как сравнение строк ». Это точно звучит как Dateтип данных, просто переносимый в аString
Росс Паттерсон

Как вы говорите, это строковое представление даты, и в отличие от оригинального постера, дата не изменяется, если она находится в часовом поясе UTC + 13.
Майкл Шоу

2

Почему нет настоящего типа данных «Только для даты»?

По тем же причинам, я думаю, что значения DateTime обычно указываются в UTC: простота и надежность . Смысл значения DateTime состоит в том, чтобы указать один момент времени, на который не влияют часовой пояс, летнее время, календарь и другие локальные настройки. Значения DateTime указывают одно мгновение (до ограничения разрешения типа), а не период времени или набор времени. Эти ограничения позволяют сравнивать значения DateTime надежным, предсказуемым, несложным способом.

Попытка указать дату со значением DateTime аналогична попытке использовать точку для указания области.Вы можете выполнить эту работу, используя соглашение, например, «эта точка представляет центр круга с радиусом 100 м», но там много проблем: всем нужно использовать одно и то же соглашение, вам нужно написать кучу поддержка кода, чтобы сделать работу с неправильным типом менее болезненной, и в значительной степени гарантировано, что в какой-то момент вам нужно будет указать область, которая больше или меньше обычной области. То же самое и с датами: вы можете использовать «полдень» в качестве обычного времени для указания дат, но затем вы попадаете в часовые пояса, потому что люди ожидают указывать даты по местному времени, а не по UTC. И даже если вы найдете приемлемый способ использования DateTime для указания даты, вам потребуется дополнительная информация, чтобы узнать, является ли она абсолютной или относительной датой: 4 июля, 1776 или каждый 4 июля? Что если вы хотите повторить, используя другой период? И у календарей есть все виды сумасшедших проблем: некоторые месяцы длиннее других, некоторые годы длиннее других, некоторые дни даже длиннее других, и в некоторых календарях есть пробелы. Вы не захотите решать эти проблемы только целыми днями, потому что одни и те же проблемы возникают в течение более коротких периодов времени: вы, вероятно, хотели бы иметь возможность писать код, который выражает «принимать по 1 таблетке каждые 4 часа» так же легко, как « группа собирается каждую третью пятницу ".

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

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


2
«Трудно предоставить тип, который обращается ко всем способам использования дат». Это правда, поэтому ужасно пытаться предоставить один тип для всего этого. Первые выпуски Java предоставляли только java.util.Date, и результат был ужасным. Затем они добавили сложную иерархию java.util.Calendar, и она не стала намного лучше.
Кевин Клайн

1
@kevincline Полностью согласен. ОП не указывал язык, поэтому я стремился к общности.
Калеб

« По тем же причинам, я думаю, что значения DateTime обычно указываются в UTC » ... О, если бы это было правдой. Это 2015 год, и все еще много кода пишется с использованием домашнего часового пояса автора :-(
Росс Паттерсон

1
Мне действительно было интересно, почему не существует общепринятого соглашения о датах. Ваше «использование точки для представления области» прекрасно отражает мое разочарование.
Майкл Блэкберн

2

Почему нет настоящего типа данных «Только для даты»?

Существует много таких типов в разных библиотеках для разных языков. Почти наверняка есть один для вашего текущего языка. У утилит Java был ужасный API для вычисления времени, но введение пакета java.time сделало жизнь намного лучше. См. Java.time.LocalDate, содержащий значение года-месяца-дня, или java.time.MonthDay, содержащий только номер месяца и дня.


1

Календарная манипуляция - один из самых плохо понимаемых аспектов вычислительной техники. Целые книги были написаны на эту тему. @MichealBlackburn абсолютно прав, когда запрашивает тип данных только для даты, который не разрешается до определенной точки на временной шкале и подлежит повторной интерпретации. Исторически существовали законные споры о значении даты. Нужно смотреть не дальше, чем принять григорианский календарь, чтобы понять, насколько сложным он может стать. Кроме того, годы не всегда начинались 1 января, даже в Западной Европе и ее колониях ( например , Британия и Британская Америка начали год 25 марта).


1
Это правильно. Часто задаваемые вопросы по календарю, которые я цитирую в своем ответе, являются отличным ресурсом, чтобы узнать о сложностях и тонкостях манипуляций с кландалами
Майкл Ле Барбье Грюневальд,

-2

В ответ на:

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

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

date = new DateTime(year, month, day, 0, 0, 0);

Если вы хотите, вы можете продлить DateTime самостоятельно:

public class Date extends DateTime {
    ...
    public Date(int year, int month, int day) {
        this(year, month, day, 0, 0, 0);
    }
}

Примечание: я намеренно игнорирую время и часовой пояс по умолчанию. Неважно, на что вы их устанавливаете, если они одинаковы для всех Date. Вы можете сделать случай для UTC. Вы можете обосновать использование часового пояса, в котором находится ваш сервер - в любом случае я не думаю, что это важно для представления неточных значений, таких какDate . То же самое со временем по умолчанию - вы можете сделать это 0, вы можете сделать это в полдень. Это не важно Если Facebook присылает мне уведомление о дне рождения в 00:01, но я родился в 23:59, мне все равно, и я не буду обижаться, что у них больше 12 часов.

Выше приведено в Java, но будет работать аналогично на любом языке с DateTimeи наследование. У Java на самом деле есть множество способов решения этой проблемы, и вышесказанное устарело (они хотят, чтобы вы использовали Calendarсейчас). Но как и другие сообщения в комментариях, некоторые языки на самом деле сделать обеспечитьDate класс, по- видимому именно по этой причине.

По всей вероятности, каждая Dateреализация, вероятно, является просто оберткой для языка DateTimeи обнуляет время. В противном случае вам потребуется дублированный код для решения таких проблем, как количество дней между двумя датами / датами или два дня.Date s (как насчет 29 февраля и 1 марта?). Такие вещи обычно решаются в DateTimeклассе. Имеет смысл повторно использовать один и тот же код для Date.


4
-1: используйте LocalDate, если вы хотите только год + месяц + день. Использование DateTime для этой цели приведет к ошибкам, когда какой-либо другой программист увидит DateTime и предположит, что он представляет момент времени.
Кевин Клайн

@kevincline Я не чувствовал, что это необходимо, потому что этот вопрос не зависит от языка. Я бы также подумал, что очевидно, что использование кода, помеченного как «Устаревший», является сценарием использования на свой страх и риск. Что еще более важно, я только использовал это в качестве примера то , что вы можете сделать в сценарии , где язык не есть LocalDate, или Dateтипа класс , и вы должны роллом своих собственного ».
Shaz

1
Но «это необходимо» для ясного краткого и правильного кода, включающего бизнес-правила о времени (в отличие от физического времени). если библиотека не предоставляет типы для номинального времени, программисту необходимо будет их придумать, и способ сделать это не начинается с «DateTime».
Кевин Клайн

@kevincline Я не понимаю, как код будет менее понятным или лаконичным. В чем разница с точки зрения программиста между new Date(2000, 1, 1);и new Date(2000, 1, 1);? Можете ли вы сказать, какой из них имеет пустые часы, минуты и секунды? Если вы беспокоитесь о дополнительных функций , показывая вверх (как setMinutes ()), то вы могли бы пойти по пути иметь Dateобертку DateTimeвместо унаследованного от него, а затем вы только разоблачить setYear, setMonth, setDay и т.д. И это, конечно , не менее правильно, чем DateTime библиотеки, которую вы используете.
Шаз

Мой фон в основном C #, который не имеет конструкции, аналогичной LocalDate. Мы просто просто DateTime и запутались, по-видимому.
Майкл Блэкберн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.