How .net stores dates/how to debug them
I was debugging an application and had to check a DateTime variable’s actual value. I was expecting something like member variables holding year, month, day, hour, etc values on the object and it will be an easy one to debug, but that was not the case, so I had to find out how to check the actual date value of a DateTime variable and learn how dates are stored in the .net framework 2.0.
First of all, as you might already know, dumping out an object with SOS can be done with the !do (or !DumpObject) command. If you are not familiar with debugging .net, using WinDbg and using the SOS debugger extension, you can find a good starter at msdn.microsoft.com/msdnmag/issues/03/06/Bugslayer/default.aspx, you can check the reference of the SOS extension at msdn.microsoft.com/msdnmag/issues/03/06/Bugslayer/default.aspx, then if you are still interested, you'll find really good articles at Doug's (blogs.msdn.com/dougste) and Tess' (blogs.msdn.com/tess) blog. So, returning back to the subject, this is what you get when dumping out a DateTime variable:
0:000> !do 01481d74
Name: System.DateTime
MethodTable: 790ff4c4
EEClass: 790ff424
Size: 16(0x10) bytes
(E:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
Field Offset Type VT Attr Value Name
40000f4 4 System.UInt64 0 instance 630992916000000000 dateData
40000f0 30 System.Int32[] 0 shared static DaysToMonth365
>> Domain:Value 002401d8:01481cf4 <<
40000f1 34 System.Int32[] 0 shared static DaysToMonth366
>> Domain:Value 002401d8:01481d34 <<
40000f2 28 System.DateTime 1 shared static MinValue
>> Domain:Value 002401d8:01481cd4 <<
40000f3 2c System.DateTime 1 shared static MaxValue
>> Domain:Value 002401d8:01481ce4 <<
The actual date value is stored in the UInt64 (long) member variable called dateData, which stores the ticks representing the date value. In my example, it is 630992916000000000. That's OK so far, but how can we get the date out from this? To convert it back without using your calculator or writing an expensive algorythm, you have to use the following DateTime constructor:
public DateTime(long ticks)
or the following static method on the DateTime class:
public static DateTime FromBinary(long dateData)
Code that does the job:
DateTime dateValue = new DateTime(630992916000000000);
Console.WriteLine(dateValue);