В нашем проекте C # нам необходимо представить дату без времени. Я знаю о существовании DateTime, однако он также включает время дня. Я хочу четко указать, что некоторые переменные и аргументы метода основаны на дате . Следовательно, я не могу использовать DateTime.Date
свойство
Какие стандартные подходы к этой проблеме? Неужто я не первая сталкиваюсь с этим? Почему Date
в C # нет класса?
Есть ли у кого-нибудь хорошая реализация с использованием структуры и, возможно, некоторых методов расширения в DateTime и, возможно, реализации некоторых операторов, таких как == и <,>?
DateTime
создает?Ответы:
Позвольте мне добавить обновление к этому классическому вопросу:
Библиотека Noda Time Джона Скита сейчас достаточно развита, и в ней используется тип только для даты
LocalDate
. (Локальный в данном случае означает просто локальный для кого-то , не обязательно локальный для компьютера, на котором выполняется код.)Вызываемый тип только с датой
Date
является предлагаемым дополнением к .NET Core через проект corefxlab . Вы найдете его вSystem.Time
пакете вместе сTimeOfDay
типом и несколькими методами расширения существующих типов.Я подробно изучил эту проблему, поэтому я также поделюсь несколькими причинами необходимости этих типов:
Существует логическое несоответствие между значением только даты и датой в полночь.
Не в каждый местный день есть полночь в каждом часовом поясе. Пример: весенний переход на летнее время в Бразилии переводит часы с 11:59:59 на 01:00:00.
Дата-время всегда относится к определенному времени в течение дня, в то время как только дата может относиться к началу дня, концу дня или всему диапазону дня.
Привязка времени к дате может привести к изменению даты по мере передачи значения из одной среды в другую, если часовые пояса не отслеживаются очень внимательно. Это обычно происходит в JavaScript (
Date
объект которого на самом деле является датой + временем), но может легко произойти и в .NET, или при сериализации, когда данные передаются между JavaScript и .NET.Сериализация
DateTime
с XML или JSON (и другими) всегда будет включать время, даже если это не важно. Это очень сбивает с толку, особенно учитывая такие вещи, как даты рождения и годовщины, когда время не имеет значения.Архитектурно
DateTime
это объект-значение DDD , но он нарушает принцип единой ответственности несколькими способами:Он разработан как тип даты + времени, но часто используется только для даты (без учета времени) или только для времени (без учета даты). (
TimeSpan
также часто используется для обозначения времени суток, но это уже другая тема.)DateTimeKind
Значение , придаваемое в.Kind
собственности делит один тип на три,Unspecified
вид действительно первоначальная цель структуры, и следует использовать таким образом. ВUtc
любезном Выравнивает значение конкретно с UTC, аLocal
любезные выравнивает значение с местным часовым поясом среды.Проблема с отдельным флагом для вида состоит в том, что каждый раз, когда вы потребляете a
DateTime
, вы должны проверять,.Kind
какое поведение предпринять. Все методы фреймворка делают это, но другие часто забывают. Это действительно нарушение SRP, поскольку тип теперь имеет две разные причины для изменения (значение и вид).Два из них приводят к использованию API, которые компилируются, но часто бессмысленны или имеют странные граничные случаи, вызванные побочными эффектами. Рассматривать:
Таким образом, хотя a
DateTime
может использоваться только для даты, он должен делать это только тогда, когда каждое место, которое его использует, очень осторожно игнорирует время, а также очень осторожно, чтобы не пытаться преобразовать в и из UTC или другого часовые пояса.источник
System.Time.Date
бы толькоSystem.Time
как любой другой пакет. Это просто еще не "официально".Я подозреваю, что нет специального чистого
Date
класса, потому что у вас уже есть тот,DateTime
который может с ним справиться. НаличиеDate
привело бы к дублированию и путанице.Если вам нужен стандартный подход, посмотрите на
DateTime.Date
свойство, которое дает только часть даты в aDateTime
со значением времени, установленным на 12:00:00 полночь (00:00:00).источник
Я написал по электронной почте refsrcfeedback@microsoft.com, и это их ответ
В своем электронном письме я спросил, было ли это из-за того, что DateTime использует TimeZoneInfo для получения времени машины - в соответствии с требованиями Now. Я бы сказал, что это потому, что «бизнес-правила» «слишком взаимосвязаны», они мне подтвердили это.
источник
SpaceTime
класс! Эй, согласно Эйнштейну, пространство и время тесно связаны, так что нам не нужно различать их, верно? (!!!!!!!!!!!) Я своего рода новым для C #, но я должен сказать, что это минное поле , исходя из VB.NET , где есть, простоdate
,Today()
,now
и т.д. НетDateTime
предваряя мусор, нет возиться. (И эти точки с запятой и эта чувствительность к регистру, конечно, утомительны! Просто стреляйте в меня сейчас!)Date
тип, а результат должен быть типаDate
- если это былDate
результат типа, ожидаемый как строка без времени. Например, Delphi также имеет Date как DateTime, но typeinfo отличается для Date и DateTime.Я создал простую структуру Date для случаев, когда вам нужна простая дата, не беспокоясь о временном отрезке, часовом поясе, локальном или utc и т. Д.
https://github.com/claycephus/csharp-date
источник
Если вам нужно выполнить сравнение дат, используйте
Если вы показываете на экран, используйте
источник
Позвольте мне порассуждать: может быть, это потому, что до SQL Server 2008 в SQL не было типа данных Date, поэтому было бы сложно хранить его на SQL-сервере ?? И это все-таки продукт Microsoft?
источник
Кто знает, почему так. В .NET framework есть много плохих дизайнерских решений. Однако я думаю, что это довольно незначительный вопрос. Вы всегда можете игнорировать временную часть, поэтому даже если какой-то код решает, что DateTime относится не только к дате, код, который заботится, должен всегда смотреть только на часть даты. В качестве альтернативы вы можете создать новый тип, представляющий только дату, и использовать функции DateTime для выполнения тяжелой работы (вычислений).
источник
Зачем? Мы можем только строить предположения, и это мало помогает в решении инженерных проблем. Хорошее предположение состоит в том, что он
DateTime
содержит все функции, которые могла бы иметь такая структура.Если это действительно важно для вас, просто оберните
DateTime
свою собственную неизменяемую структуру, которая отображает только дату (или посмотрите наDateTime.Date
свойство).источник
В дополнение к ответу Роберта у вас также есть
DateTime.ToShortDateString
метод. Кроме того, если вам действительно нужен объект Date, вы всегда можете использовать шаблон адаптера и обернуть объект DateTime, выставляя только то, что вы хотите (например, месяц, день, год).источник
Всегда есть
DateTime.Date
свойство, которое отсекает временную частьDateTime
. Возможно, вы можете инкапсулировать или обернуть DateTime в свой собственный тип даты.И на вопрос, почему, я думаю, вам придется спросить Андерса Хельсберга.
источник
Потому что, чтобы узнать дату, вам нужно знать системное время (в тиках), которое включает время - так зачем выбрасывать эту информацию?
DateTime
у вас естьDate
собственность, если вас совсем не волнует время.источник
Да, System.DateTime тоже запечатан. Я видел, как некоторые люди играли в игры с этим, создавая собственный класс, просто чтобы получить строковое значение времени, как упоминалось в предыдущих сообщениях, например:
Возможно, в этом нет необходимости, поскольку вы можете легко извлечь GetShortTimeString из простого старого типа DateTime без нового класса.
источник
Если вы используете свойства Date или Today для получения только части даты из объекта DateTime.
Тогда вы получите компонент даты только с компонентом времени, установленным на полночь.
источник