DateTime "нулевое" значение

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

Решение

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

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

DateTime? MyNullableDate;

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

Nullable MyNullableDate;

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

default(DateTime)
Комментарии (5)

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

DateTime? dt = null;

или

Nullable 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

Комментарии (6)

DateTime? MyDateTime {get; set;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
Комментарии (1)

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

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

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

Комментарии (0)

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

DateTime? myDate вместо DateTime myDate.

Комментарии (0)

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

DateTime? date = new DateTime?();
Комментарии (1)

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

Nullable myDateTime;

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

DateTime? myDateTime;
Комментарии (0)

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


DateTime date;
...
if(date == null) // 
Комментарии (0)

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

Комментарии (9)

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

DateTime? nullDate = null;

или

DateTime? nullDate;
Комментарии (0)

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

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

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

  1. Использование свойства Nullable.Value

    DateTime date = myNullableObject.Value.ToUniversalTime (); //Works

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

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

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

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

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

Комментарии (0)

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

[ERROR: не могу конвертировать system.datetime? на system.datetime]

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

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

Комментарии (0)

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

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

В вашем хранилище используйте null-able datetime.

public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
Комментарии (0)

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

Assert.Throws(()=>sut.StartingDate = DateTime.Parse(null));
Комментарии (0)

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

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

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

Позвольте мне продемонстрировать мой первый пункт, используя пример. Тип переменной DateTime не может быть установлен на ноль, ему нужно значение, в этом случае я собираюсь установить его на минимальное значение 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(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue(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(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue(1);

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

Комментарии (0)