Вопрос

Я много искал, но не смог найти решения.Как вы поступаете с DateTime, который должен содержать неинициализированное значение (эквивалентное нулю)?У меня есть класс, который может иметь установленное значение свойства DateTime или нет.Я думал об инициализации владельца свойства DateTime.MinValue, который затем можно было бы легко проверить.Думаю, это довольно распространенный вопрос: как это сделать?

Это было полезно?

Решение

Для обычных DateTimes, если вы их вообще не инициализируете, они будут соответствовать DateTime.MinValue , потому что это тип значения, а не ссылочный тип.

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

DateTime? MyNullableDate;

Или более длинная форма:

Nullable<DateTime> MyNullableDate;

И, наконец, есть встроенный способ ссылки на тип по умолчанию любого типа. Это возвращает null для ссылочных типов, но для нашего примера DateTime оно возвращает то же самое, что и DateTime.MinValue :

default(DateTime)

Другие советы

Если вы используете .NET 2.0 (или более позднюю версию), вы можете использовать обнуляемый тип:

DateTime? dt = null;

или

Nullable<DateTime> dt = null;

потом позже:

dt = new DateTime();

И вы можете проверить значение с помощью:

if (dt.HasValue)
{
  // Do something with dt.Value
}

Или вы можете использовать его следующим образом:

DateTime dt2 = dt ?? DateTime.MinValue;

Вы можете прочитать больше здесь:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx

ДатаВремя?MyDateTime {получить; установить;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);

Следующий способ также работает

myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;

Обратите внимание, что свойство PublishDate должно быть DateTime?

Я бы хотел использовать обнуляемые типы .

<код> DateTime? myDate вместо DateTime myDate .

Вы можете использовать обнуляемый класс.

DateTime? date = new DateTime?();

Для этого вы можете использовать обнуляемый DateTime.

Nullable<DateTime> myDateTime;

или то же самое, написанное так:

DateTime? myDateTime;

Я всегда устанавливаю время на DateTime.MinValue . Таким образом, я не получаю никакого исключения NullErrorException и могу сравнить его с датой, которую я знаю, не установлено.

Стоит отметить, что хотя переменная DateTime не может быть null , ее все равно можно сравнить с null без ошибки компилятора

DateTime date;
...
if(date == null) // <-- will never be 'true'
  ...

Вы можете установить DateTime в Nullable. По умолчанию DateTime не обнуляется. Вы можете сделать его обнуляемым несколькими способами. Использование знака вопроса после типа DateTime? myTime или используя общий стиль Nullable. Я добавил пару ссылок на MSDN.

Использование Nullable

Nullable

Просто предупреждаем - при использовании Nullable он, очевидно, больше не является «чистым» объектом datetime, поэтому вы не можете напрямую обращаться к членам DateTime. Я постараюсь объяснить.

Используя Nullable < > вы, по сути, оборачиваете DateTime в контейнер (спасибо вам за дженерики), который может быть обнуляем - очевидно, его цель. Этот контейнер имеет свои собственные свойства, которые вы можете вызвать, что обеспечит доступ к вышеупомянутому объекту DateTime; после использования правильного свойства - в данном случае Nullable.Value - вы получаете доступ к стандартным элементам DateTime, свойствам и т. д.

Итак - теперь возникает вопрос о том, как лучше всего получить доступ к объекту DateTime. Есть несколько способов, номер 1 по FAR лучший, а 2 - "чувак, почему".

<Ол>
  • Используя свойство Nullable.Value,

    DateTime date = myNullableObject.Value.ToUniversalTime (); // Труды

    DateTime date = myNullableObject.ToUniversalTime (); // Не объект datetime, не удается

  • Преобразование обнуляемого объекта в datetime с использованием Convert.ToDateTime (),

    DateTime date = Convert.ToDateTime (myNullableObject) .ToUniversalTime (); // работает, но почему ...

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

    edit: удален третий вариант, так как он был слишком специфичным и зависимым от регистра.

    Хотя все уже дали вам ответ, я упомяну способ, который облегчает передачу даты и времени в функцию

    [ОШИБКА: не удалось преобразовать system.datetime? to system.datetime]

    DateTime? dt = null;
    DateTime dte = Convert.ToDateTime(dt);
    

    Теперь вы можете передавать dte внутри функции без проблем.

    Если вы иногда ожидаете нулевое значение, вы можете использовать что-то вроде этого:

    var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)
    

    В вашем репозитории используйте нулевую дату и время.

    public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
    

    У меня была та же проблема, что и для задания значения DateTime в качестве параметра для DateTime, когда я выполнял модульный тест для Throws ArgumentNullException. В моем случае это работало с использованием следующей опции:

    Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
    

    Учитывая природу типа данных даты/времени, он не может содержать null ценность, т.е.он должен содержать значение, он не может быть пустым или ничего не содержать.Если вы пометите переменную даты/времени как nullable только тогда вы сможете присвоить ему нулевое значение.Итак, вы хотите сделать одно из двух (их может быть больше, но я могу думать только о двух):

    • Присвойте минимальное значение даты/времени вашей переменной, если у вас нет для нее значения.Вы также можете назначить максимальное значение даты/времени — любой способ, который вам подходит.Просто убедитесь, что вы единообразны на всем сайте при проверке значений даты и времени.Примите решение об использовании min или max и придерживайтесь этого.

    • Отметьте переменную даты/времени как nullable.Таким образом, вы можете установить переменную даты/времени на null если у вас нет переменной для него.

    Позвольте мне продемонстрировать мою первую мысль на примере.А DateTime Тип переменной не может быть установлен в значение null, ему нужно значение, в этом случае я собираюсь установить его в значение DateTimeминимальное значение, если значение отсутствует.

    Мой сценарий заключается в том, что у меня есть BlogPost сорт.У него много разных полей/свойств, но в этом примере я решил использовать только два. DatePublished это когда сообщение было опубликовано на веб-сайте и должно содержать значение даты/времени. DateModified это когда сообщение изменено, поэтому оно не обязательно должно содержать значение, но может содержать значение.

    public class BlogPost : Entity
    {
         public DateTime DateModified { get; set; }
    
         public DateTime DatePublished { get; set; }
    }
    

    С использованием ADO.NET чтобы получить данные из базы данных (назначьте DateTime.MinValue нет значения):

    BlogPost blogPost = new BlogPost();
    blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
    blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
    

    Вы можете выполнить мой второй пункт, отметив DateModified поле как nullable.Теперь вы можете установить его на null если для него нет значения:

    public DateTime? DateModified { get; set; }
    

    С использованием ADO.NET чтобы получить данные из базы данных, это будет выглядеть немного иначе, чем это было сделано выше (присвоение null вместо DateTime.MinValue):

    BlogPost blogPost = new BlogPost();
    blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
    blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
    

    Я надеюсь, что это поможет прояснить любую путаницу.Учитывая, что мой ответ пришел примерно через 8 лет, вы, вероятно, уже являетесь экспертом-программистом C# :)

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top