Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on May 3rd, 2012  |  syntax: C#  |  size: 2.94 KB  |  views: 125  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // Adapted from http://msmvps.com/blogs/jon_skeet/archive/2012/05/02/more-fun-with-datetime.aspx
  2.  
  3. using System;
  4. using System.Diagnostics;
  5. using System.Runtime.InteropServices;
  6.  
  7. [StructLayout(LayoutKind.Explicit, Size = 8)]
  8. struct DateTimeUnion
  9. {
  10.     [FieldOffset(0)]
  11.     public DateTime datetime;
  12.     [FieldOffset(0)]
  13.     public ulong value;
  14. }
  15.  
  16. public class DateTimesDeepDarkSecret
  17. {
  18.     static string DumpDate(DateTime date)
  19.     {
  20.         DateTimeUnion foo = new DateTimeUnion();
  21.         foo.datetime = date;
  22.         ulong flags = foo.value >> 62;
  23.         ulong ticks = foo.value & 0x3FFFFFFFFFFFFFFF;
  24.         Debug.Assert((long)ticks == date.Ticks);
  25.         return String.Format("{{flags:{0:x}, ticks:{1:x}, datetime:{2}}}", flags, ticks, date);
  26.     }
  27.  
  28.     public static void Main()
  29.     {
  30.         // Start with different UTC values around a DST transition
  31.         var original1 = new DateTime(2012, 10, 28, 0, 20, 0, DateTimeKind.Utc);
  32.         var original2 = new DateTime(2012, 10, 28, 1, 20, 0, DateTimeKind.Utc);
  33.  
  34.         // Convert to local time
  35.         var local1 = original1.ToLocalTime();
  36.         var local2 = original2.ToLocalTime();
  37.  
  38.         // Result is the same for both values. Information loss?
  39.         var expected = new DateTime(2012, 10, 28, 1, 20, 0, DateTimeKind.Local);
  40.         Console.WriteLine(local1 == expected); // True
  41.         Console.WriteLine(local2 == expected); // True
  42.         Console.WriteLine(local1 == local2);   // True
  43.  
  44.         // Convert back to UTC
  45.         var roundTrip1 = local1.ToUniversalTime();  
  46.         var roundTrip2 = local2.ToUniversalTime();
  47.  
  48.         // Values round-trip correctly! Information has been recovered...
  49.         Console.WriteLine(roundTrip1 == original1);  // True
  50.         Console.WriteLine(roundTrip2 == original2);  // True
  51.         Console.WriteLine(roundTrip1 == roundTrip2); // False
  52.  
  53.         var local3 = local1.AddYears(-1).AddDays(2);  
  54.         var local4 = local2.AddYears(-1).AddDays(2);        
  55.         Console.WriteLine(local3.ToUniversalTime().Hour); // 0
  56.         Console.WriteLine(local4.ToUniversalTime().Hour); // 1
  57.  
  58.         // Should be a no-op?
  59.         var local5 = DateTime.SpecifyKind(local1, local1.Kind);  
  60.         Console.WriteLine(local5.ToUniversalTime().Hour); // 1
  61.  
  62.         Console.WriteLine("original1:  {0}", DumpDate(original1));
  63.         Console.WriteLine("original2:  {0}", DumpDate(original2));
  64.         Console.WriteLine("local1:     {0}", DumpDate(local1));
  65.         Console.WriteLine("local2:     {0}", DumpDate(local2));
  66.         Console.WriteLine("expected:   {0}", DumpDate(expected));
  67.         Console.WriteLine("roundTrip1: {0}", DumpDate(roundTrip1));
  68.         Console.WriteLine("roundTrip2: {0}", DumpDate(roundTrip2));
  69.         Console.WriteLine("local3:     {0}", DumpDate(local3));
  70.         Console.WriteLine("local4:     {0}", DumpDate(local4));
  71.         Console.WriteLine("local5:     {0}", DumpDate(local5));
  72.     }
  73. }