it-swarm.com.ru

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

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

249
Mats

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

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

DateTime? MyNullableDate;

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

Nullable<DateTime> MyNullableDate;

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

default(DateTime)
391
Joel Coehoorn

Если вы используете .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

81
Mark Ingram

DateTime? MyDateTime {получить, установить;}

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

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

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

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

22
Aleksei

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

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

12
David Mohundro

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

DateTime? date = new DateTime?();
6
Aaron Smith

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

Nullable<DateTime> myDateTime;

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

DateTime? myDateTime;
6
Patrik Svensson

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

5
Patrick Desjardins

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

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

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

используя Nullable

Nullable

4
user29958

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

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

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

  1. Используя свойство Nullable.Value,

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

    DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails

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

    DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why...

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

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

3
Gabe

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

[ОШИБКА: невозможно преобразовать system.datetime? В system.datetime]

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

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

2
No Holidays

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

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

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

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

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

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

Учитывая природу типа данных даты/времени, он не может содержать значение 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 # :)

0
Brendan Vogt