Iris Classon
Iris Classon - In Love with Code

‘Stupid’ Question 32: How do you check if the value for a DateTime property is set?

[To celebrate my first year of programming I will ask a ‘stupid’ questions daily on my blog for a year, to make sure I learn at least 365 new things during my second year as a developer]

Can time be null? Not unless you say it can

Today I was looking for an alternative way to check if DateTime as been assigned a value or not, if I’m not using a nullable type. I was just curious if this could be done. The thing is, DateTime is a Value type,- so it can’t be null unless you of course make it a nullable type. Value types are stored as the value they are assigned, in contrast to reference types that point to an object - and thus it makes no sense having a value type with the value of null .

A nullable type lets you represent a value type as anything within the set range, or as null. Now, what if you, for whatever reason, don’t want to make a value a nullable type? What you can do is to use the DateTime.MinValue, which is the smallest possible value that a DateTime can have, and also the value an unassigned DateTime has.

I reckon that is makes more sense to make DateTime a nullable type, what do you think? When would be a good time to use DateTime.MinValue?

Comments

Leave a comment below, or by email.
Yngve Bakken Nilsen
8/27/2012 10:09:12 AM
We also use Nullable datetimes alot. The problem often is that if, for some reason, the date is not set implicitly by the consumer, the default date is still a valid Date (until you try to store it to a db, for instance...), hence it's hard to check for the validity of a date. 

Although, you could argue that you often want range-validation on your DateTime anyway.. Unless you're making a calendar from the beginning of time, the date 01.01.0001 doesn't really make much sense. So probably somethink like if(theDateTime < new DateTime(1900, 01, 01)) { throw new ThatDateDoesntMakeSenseException(); } can be just as good as a check against DateTime.MinValue 
Sander Kooij
8/27/2012 10:09:49 AM
I think the best thing you can do is look at the default value of the value type. In case of DateTime this is DateTime.MinValue. So DateTime dateTime = default(DateTime);. It's not a guarantee, but I normally use this to indicate that a value has not yet been set. 
SondreB
8/27/2012 10:14:06 AM
I want to note that the "datetime2" column type on SQL Server pre-2012 supports DateTime.MinValue in .NET. I do think that SQL Server 2012 now supports DateTime.MinValue with the default datetime column type, but not sure? 
David
8/27/2012 10:14:14 AM
I usually use nullable types for DateTime structs. However, you can use DateTime.MinValue as well. Its really your preference in my opinion. As long as you are consistent with its use I don't think either method is bad. 
matt bialko
8/27/2012 10:14:27 AM
I either will use a nullable datetime (DateTime? nullDate = null;) or I will default the value MinValue like (DateTime nullDate = DateTime.MinValue;). Both will work, you just have to be consistent!

Love your blog, Iris! 
Yngve Bakken Nilsen
8/27/2012 10:15:33 AM
Reply to: SondreB
Haven't tried that myself, but still - what good is the date 01.01.0001? When would you ever want that in you data. In my opinion, it's bad data... 
Yngve Bakken Nilsen
8/27/2012 10:18:45 AM
Reply to: Sander Kooij
Do you mean that applies to other valuetypes as well? the default value of Int is 0, and in many cases that will be a valid value... 
James Curran
8/27/2012 10:21:47 AM
One advantage of using DateTime.MinValue is that it is a valid value.  i.e.
      if (startDate < DateTime.Now) 
will work is startDate is MinValue or a specific date.

In fact, if you want the unassigned/default/null value to mean "include all dates" then you'll probably need to do this anyway:
if (startDate.IsNull) startDate = DateTimeMinValue;
if (EndDate.IsNull) endDate = DateTime.MaxValue; 
Shayne
8/27/2012 10:24:00 AM
It depends, right?  There are a few ways, given the language of choice. Now in your world, you have chosen C# and typically unless you have declared that the DateTime can be null; the best option is 

DateTime dt;

...

if (dt == DateTime.MinValue)
     DoSomething();

However, IF dt is declare as a nullable type then

if (dt == null || dt == DateTime.MinValue)
    DoSomething();

In VB.NET you can always revert to the Date helper classes with 

If IsDate(dt) Then
     DoSomeThing()
End If 
Amit
8/27/2012 10:26:33 AM
Well DateTime is a struct and so called a value type. and its a composition of different value types so making nullable doesn't make sense. Better go with a default value so called DateTime.MinValue. 

hope this make sense. 

cheers!! 
Tyrone
8/27/2012 10:31:57 AM
Just set a date far enough where we would either be all dead or the application would probably be re-written by that time and use it as the default state of the data object. DateTime.MinValue and DateTime.MaxValue does the job as well. 
Kristof Claes
8/27/2012 10:45:42 AM
Reply to: Yngve Bakken Nilsen
In that case, I'd just check if the DateTime is valid for SQL Server:


public static bool IsValidForSqlServer(this DateTime date)
{
    if (date < (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue)
    {
        return false;
    }

    if (date > (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue)
    {
        return false;
    }

    return true;
}
 
Ian Quigley
8/27/2012 10:49:29 AM
Use DateTime.MinValue.Subtract(TimeSpan.FromSeconds(1)) to avoid confusing with default(DateTime)

:-) 
Yngve Bakken Nilsen
8/27/2012 10:53:18 AM
Reply to: Kristof Claes
Of course, but my point was not necessarily only when saving to a Database. The DateTime.Minvalue (or MaxValue for that matter), is in 99% of the cases "Invalid data", and hence it might as well be nullable. 
James Curran
8/27/2012 10:53:41 AM
Reply to: Yngve Bakken Nilsen
Well, I guess it depends on whether you are planning on storing the value or just using it as a range.

e.g.,  
For a birthday field, I would definitely use a DateTime? with null meaning "no date given".

OTOH, in an input field, for a "display records within the date range", I'd use the value type with MinValue & MaxValue as the defaults, meaning "given me everything since the beginning (until the end) of the records on file" 
Cosmin.Net
8/27/2012 10:54:25 AM
using DateTime.Min or Max is using "magic values" and giving them more meaning then they are worth. when representing an interval i would just use nullable type rather then Min/Max. more logical to have a null value representing a open interval.
using DateTime.MinValue with the db can also get you into invalid types, especially when using smallDateTime. would rather have nullable on the front end, and smalldatetime (nullable) on the db. i think it's more natural to use nullable to signify "no value" than to use MinValue/MaxValue.
cases when i see this fit? can't think of one now. anyway, as someone said before, go for any but be consistent. 
Sander Kooij
8/27/2012 11:01:50 AM
Reply to: Yngve Bakken Nilsen
Yes, as far as I known you can use the default keyword for all value types. Including int, bool, float, etc. To be more precise all types deriving from System.ValueType 
Yngve Bakken Nilsen
8/27/2012 11:08:08 AM
Reply to: Sander Kooij
I know you can, but I don't think it's a good idea :) 
SondreB
8/27/2012 12:40:23 PM
Reply to: Yngve Bakken Nilsen
DateTime.MinValue (or another low value) can often be better than null in scenarios where you are doing SQL queries that work with the date field. There are many different scenarios where it could apply, and even the use of MaxValue as well. When doing integrations with third parties, it also often better to always return a date than nothing. I do use nullable date objects myself most of the time, but there are some uses for default dates as well in certain scenarios. 
matt bialko
8/27/2012 12:42:24 PM
Reply to: matt bialko
Null is by far my preferred route, because datetime.min or max might have you saying worthless info to your db. 
Anders Holmström
8/28/2012 1:00:22 AM
I do daily work with a (relatively) legacy MSSQL database and almost every table has a couple of dates in them. They are all nullable and I find that the easiest way to handle them is:


DateTime? dt = null;
var dateValue = dt.GetValueOrDefault(); //great method on all nullables!
//this is now true: dateValue == DateTime.MinValue


GetValueOrDefault() is great for using nullable datetimes (for compatibility) while at the same time easily making sure they have *some* value in the code. I vastly prefer this to storing a magic value in the database. 
Fredrik Mörk
8/28/2012 4:13:30 AM
I usually like my code to be unambiguous. If you want to describe that a variable has no valid value, you should not use one of the type's valid values to describe it. I do not hesitate to use Nullable wherever it makes sense. I do hesitate not to, on the other hand.

Before Nullable graced us with its presence, I sometimes saw a pattern where you would "pair" properties. So if you had a property "DateTime CreatedDate", there would also be a "Bool CreatedDateIsNull" or so, which would indicate whether or not CreatedDate had gotten a valid value assigned. I would not dream of using such a pattern today, when Nullable solves this problem in a much clearer way. 
matt bialko
8/28/2012 5:08:22 AM
Reply to: Fredrik Mörk
Well said. I have too seen this pattern and like nullable much much better! 
Sacs
8/29/2012 1:57:43 AM
I tend to avoid nullable types where possible as others consuming the code may be expecting a simple value type and not check for the null. 
Matt Heffron
9/6/2012 4:09:47 PM
Reply to: Amit
It is true that DateTime is a struct, but under-the-covers it is just a ulong, so making it nullable makes just as much sense as for any other value type. 
Matt Heffron
9/6/2012 4:12:19 PM
Reply to: Ian Quigley
You can't do this! The resulting value is out of range and throws an exception! 
Matt Heffron
9/6/2012 4:21:17 PM
If you're going to make the DateTime be nullable, then explicitly checking for the null value obscures the intent of being nullable in the first place. 
Use the .HasValue property, as that makes the intent more apparent to future developers who may look at the code.
Also, use of the null coalescing operator (??) is very apropriate with nullable data types. 
cronynaval
11/20/2014 12:21:03 AM
Nullable  nullDateTime; 
or
DateTime? nullDateTime = null; 
Full source..Nullable DateTime 

Crony 


Last modified on 2012-08-26

comments powered by Disqus