New Psscor2 commands – Dealing with Dates and Times

If you have ever tried to look at a System.DateTime or System.TimeSpan object in a debugger, you know how difficult it is to see what the value is.  For example, this is what a System.DateTime object looks like:

 0:017> !do 0x040f59b8 
Name: System.DateTime
MethodTable: 60809f0c
EEClass: 605e1fd8
Size: 16(0x10) bytes
GC Generation: 2
 (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
6080ab9c  40000f4        4        System.UInt64  1 instance 633739266270770000 dateData
6082aa5c  40000f0       30       System.Int32[]  0   shared   static DaysToMonth365
    >> Domain:Value  0097ce58:03d6cad0 <<
6082aa5c  40000f1       34       System.Int32[]  0   shared   static DaysToMonth366
    >> Domain:Value  0097ce58:03d6cb10 <<
60809f0c  40000f2       28      System.DateTime  1   shared   static MinValue
    >> Domain:Value  0097ce58:03d6cab0 <<
60809f0c  40000f3       2c      System.DateTime  1   shared   static MaxValue
    >> Domain:Value  0097ce58:03d6cac0 <<

Figuring out what time this is can be very difficult.

This is where some of the new commands in psscor2 can really help you out.  There are a few different commands so let me explain them each so you can use them when you need to.

!PrintDateTime

The first one is !PrintDateTime.  This command takes a System.DateTime object or a System.TimeSpan object and prints it out as a date.  For example:

 0:017> !printdatetime 0x0420e658 
As a TimeSpan: 733494.12:30:27.0770000
As a DateTime: 03/29/2009 12:30:27

It will always print out both as there is no way to tell if the object is really a System.DateTime or a System.TimeSpan as both are stored in a System.DateTime object. 

So in this example, it is a DateTime and we call tell that because the DateTime is a valid time.  For a TimeSpan, the output will look something like:

 0:017> !printdatetime 0x040f59b8 
As a TimeSpan: 25.00:00:00
As a DateTime: 01/01/1753 00:00:00

!ConvertTicksToDate (ctd)

This command works against the actual ticks (dateData field of the DateTime object).  It works the same way, but sometimes you will have objects that store ticks so it is nice to be able to run this directly against them.  The output looks the same:

 0:017> !ctd 633739266270770000
As a TimeSpan: 733494.12:30:27.0770000
As a DateTime: 03/29/2009 12:30:27

!ConvertVTDateToDate (cvtdd)

This command is useful when the DateTime you are looking at is a Value Type.  In this case, if you try to use the other commands, you will get errors because there is no Method Table for the object.  You can see here that the _startTime has a 1 set for the VT column so it is a value type object:

 0:000> !do 0x18346ff4 
Name: System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6
MethodTable: 68a1f7c8
EEClass: 68a1f748
Size: 252(0xfc) bytes
GC Generation: 0
 (C:\WINNT\assembly\GAC_32\System.Web\2.0.0.0__b03f5f7f11d50a3a\System.Web.dll)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79105ef0  4001294        4      System.DateTime  1 instance 18346ff8 _startTime

If you !do this, you will get:

 0:000> !do 18346ff8 
<Note: this object has an invalid CLASS field>
Invalid object

!PrintDateTime will show the correct output, of if you use !cvtdd:

 0:000> !cvtdd 18346ff8 
As a TimeSpan: 6070081.06:18:02.6363604
As a DateTime: 06/20/2006 16:53:59

Let me know what you guys think of these new commands.