I've been searching a lot but couldn't find a solution. How do you deal with a DateTime that should be able to contain an uninitialized value (equivalent to null)? I have a class which might have a DateTime property value set or not. I was thinking of initializing the property holder to DateTime.MinValue, which then could easily be checked. I guess this is a quite common question, how do you do that?
15 Answers
For normal DateTimes, if you don't initialize them at all then they will match DateTime.MinValue, because it is a value type rather than a reference type.
You can also use a nullable DateTime, like this:
DateTime? MyNullableDate;
Or the longer form:
Nullable<DateTime> MyNullableDate;
And, finally, there's a built in way to reference the default of any type. This returns null for reference types, but for our DateTime example it will return the same as DateTime.MinValue:
default(DateTime)
or, in more recent versions of C#,
default
If you're using .NET 2.0 (or later) you can use the nullable type:
DateTime? dt = null;
or
Nullable<DateTime> dt = null;
then later:
dt = new DateTime();
And you can check the value with:
if (dt.HasValue)
{
// Do something with dt.Value
}
Or you can use it like:
DateTime dt2 = dt ?? DateTime.MinValue;
You can read more here:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx
Just be warned - When using a Nullable its obviously no longer a 'pure' datetime object, as such you cannot access the DateTime members directly. I'll try and explain.
By using Nullable<> you're basically wrapping DateTime in a container (thank you generics) of which is nullable - obviously its purpose. This container has its own properties which you can call that will provide access to the aforementioned DateTime object; after using the correct property - in this case Nullable.Value - you then have access to the standard DateTime members, properties etc.
So - now the issue comes to mind as to the best way to access the DateTime object. There are a few ways, number 1 is by FAR the best and 2 is "dude why".
Using the Nullable.Value property,
DateTime date = myNullableObject.Value.ToUniversalTime(); //WorksDateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, failsConverting the nullable object to datetime using Convert.ToDateTime(),
DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why...
Although the answer is well documented at this point, I believe the usage of Nullable was probably worth posting about. Sorry if you disagree.
edit: Removed a third option as it was a bit overly specific and case dependent.
Although everyone has already given you the answer , I'll mention a way which makes it easy to pass a datetime into a function
[ERROR:cannot convert system.datetime? to system.datetime]
DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);
Now you may pass dte inside the function without any issues.
Given the nature of a date/time data type it cannot contain a null value, i.e. it needs to contain a value, it cannot be blank or contain nothing. If you mark a date/time variable as nullable then only can you assign a null value to it. So what you are looking to do is one of two things (there might be more but I can only think of two):
Assign a minimum date/time value to your variable if you don't have a value for it. You can assign a maximum date/time value as well - whichever way suits you. Just make sure that you are consistent site-wide when checking your date/time values. Decide on using
minormaxand stick with it.Mark your date/time variable as
nullable. This way you can set your date/time variable tonullif you don't have a variable to it.
Let me demonstrate my first point using an example. The DateTime variable type cannot be set to null, it needs a value, in this case I am going to set it to the DateTime's minimum value if there is no value.
My scenario is that I have a BlogPost class. It has many different fields/properties but I chose only to use two for this example. DatePublished is when the post was published to the website and has to contain a date/time value. DateModified is when a post is modified, so it doesn't have to contain a value, but can contain a value.
public class BlogPost : Entity
{
public DateTime DateModified { get; set; }
public DateTime DatePublished { get; set; }
}
Using ADO.NET to get the data from the database (assign DateTime.MinValue is there is no value):
BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
You can accomplish my second point by marking the DateModified field as nullable. Now you can set it to null if there is no value for it:
public DateTime? DateModified { get; set; }
Using ADO.NET to get the data from the database, it will look a bit different to the way it was done above (assigning null instead of DateTime.MinValue):
BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
I hope this helps to clear up any confusion. Given that my response is about 8 years later you are probably an expert C# programmer by now :)