次の方法で共有


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);