Я много искал, но не смог найти решение. Как вы справляетесь с DateTime, который должен содержать неинтилизованное значение (эквивалентное нулю)? У меня есть класс, который может иметь значение свойства DateTime или нет. Я думал о инициализации владельца недвижимости в DateTime.MinValue, который затем можно было легко проверить. Я думаю, это довольно распространенный вопрос, как ты это делаешь?
Для обычных DateTimes, если вы их вообще не инициализируете, они будут соответствовать DateTime.MinValue < / code >, поскольку это тип значения, а не тип ссылки.
Вы также можете использовать нулевой 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
DateTime? MyDateTime {get; set;}
MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
Следующий путь тоже работает
myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;
Обратите внимание, что свойство PublishDate должно быть DateTime?
Вы можете использовать нулевой класс.
DateTime? date = new DateTime?();
Вы можете использовать нулевой DateTime для этого.
Nullable<DateTime> myDateTime;
или то же самое написано так:
DateTime? myDateTime;
Я всегда устанавливаю время на DateTime.MinValue < / code >. Таким образом, я не получаю NullErrorException и могу сравнить его с датой, которая, как я знаю, не установлена.
Вы можете установить DateTime на Nullable. По умолчанию DateTime не является недействительным. Вы можете сделать его недействительным несколькими способами. Использование знака вопроса после типа DateTime? myTime или использование общего стиля Nullable < DateTime >.
DateTime? nullDate = null;
или
DateTime? nullDate;
Просто будьте осторожны - при использовании Nullable он, очевидно, больше не является «чистым» объектом datetime, поэтому вы не можете получить прямой доступ к участникам DateTime. Я постараюсь объяснить.
Используя Nullable < > Вы в основном оборачиваете DateTime в контейнер (спасибо, дженерики), который является недействительным - очевидно, его цель. Этот контейнер имеет свои собственные свойства, которые вы можете вызвать, которые обеспечат доступ к вышеупомянутому объекту DateTime; после использования правильного свойства - в данном случае Nullable < T > .Value - у вас будет доступ к стандартным членам DateTime, свойствам и т. д.
Итак, теперь возникает проблема с лучшим способом доступа к объекту DateTime. Есть несколько способов, номер 1 по FAR лучший, а 2 «чувак почему».
Использование свойства Nullable.Value
DateTime date = myNullableObject.Value.ToUniversalTime (); //Works
DateTime date = myNullableObject.ToUniversalTime (); // Не объект datetime, не работает
Преобразование нулевого объекта в datetime с помощью Convert.ToDateTime ()
DateTime date = Convert.ToDateTime (myNullableObject). ToUniversalTime (); // работает, но почему...
Хотя ответ на данный момент хорошо документирован, я полагаю, что использование Nullable, вероятно, стоило опубликовать. Извините, если вы не согласны.
редактировать: удалил третий вариант, так как он был слишком конкретным и зависел от случая.
Хотя все уже дали вам ответ, я упомяну способ, который позволяет легко перенести дату и время в функцию
[ERROR: не могу конвертировать system.datetime? на system.datetime]
DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);
Теперь вы можете передать dte внутри функции без каких-либо проблем.
Если вы иногда ожидаете ноль, вы можете использовать что-то вроде этого:
var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)
В вашем хранилище используйте null-able datetime.
public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
У меня была та же проблема, что и у Null в качестве параметра для DateTime при выполнении теста Unit для Throws ArgumentNullException. В моем случае это работало с использованием следующей опции:
Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
Учитывая характер типа данных даты / времени, он не может содержать значение 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<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 # программистом :)