{"id":45211,"date":"2015-07-06T07:00:00","date_gmt":"2015-07-06T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20150706-00\/?p=45211\/"},"modified":"2019-03-13T12:17:03","modified_gmt":"2019-03-13T19:17:03","slug":"20150706-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150706-00\/?p=45211","title":{"rendered":"Trying out all the different ways of recognizing different types of timestamps from quite a long way away"},"content":{"rendered":"<p>Today&#8217;s Little Program takes a 64-bit integer and tries to interpret it <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2003\/09\/05\/54806.aspx\">in all the various timestamp formats<\/a>. This comes in handy when you have extracted a timestamp from a crash dump and want to see it in a friendly format. <\/p>\n<pre>\nusing System;\n\nclass Program\n{\n static void TryFormat(string format, Func&lt;DateTime&gt; func)\n {\n  try\n  {\n   DateTime d = func();\n   Console.WriteLine(\"{0} {1}\", format, d);\n  }\n  catch (ArgumentException)\n  {\n   Console.WriteLine(\"{0} - invalid\", format);\n  }\n }\n<\/pre>\n<p>The <code>Try&shy;Format<\/code> method executes the passed-in function inside a try\/catch block. If the function executes successfully, then we print the result. If it raises an argument exception, then we declare the value as invalid. <\/p>\n<pre>\n static DateTime DateTimeFromDosDateTime(long value)\n {\n  if ((ulong)value &gt; 0x00000000FFFFFFFF) {\n   throw new ArgumentOutOfRangeException();\n  }\n  int intValue = (int)value;\n  int year = (intValue &gt;&gt; 25) &amp; 127;\n  int month = (intValue &gt;&gt; 21) &amp; 15;\n  int day = (intValue &gt;&gt; 16) &amp; 31;\n  int hour = (intValue &gt;&gt; 11) &amp; 31;\n  int minute = (intValue &gt;&gt; 5) &amp; 63;\n  int second = (intValue &lt;&lt; 1) &amp; 63;\n  return new DateTime(1980 + year, month, day, hour, minute, second);\n }\n<\/pre>\n<p>The <code>Date&shy;Time&shy;From&shy;Dos&shy;Date&shy;Time<\/code> function treats the 64-bit value as a 32-bit date\/time stamp in MS-DOS format. Assuming the value fits in a 32-bit integer, we extract the bitfields corresponding to the year, month, day, hour, minute, and second, and construct a <code>Date&shy;Time<\/code> from it. <\/p>\n<pre>\n public static void Main(string[] args)\n {\n  if (args.Length &lt; 1) return;\n\n  long value = <!-- backref: Parsing a string as a 64-bit integer, somehow -->ParseLongSomehow<\/a>(args[0]);\n\n  Console.WriteLine(\"Timestamp {0} (0x{0:X}) could mean\", value);\n\n  TryFormat(\"Unix time\",\n    () =&gt; DateTime.FromFileTimeUtc(<a HREF=\"http:\/\/blogs.msdn.com\/b\/brada\/archive\/2003\/07\/30\/50205.aspx\">10000000 * value + 116444736000000000<\/a>));\n  TryFormat(\"UTC FILETIME\",\n    () =&gt; DateTime.FromFileTimeUtc(value));\n  TryFormat(\"Local FILETIME\",\n    () =&gt; DateTime.FromFileTime(value));\n  TryFormat(\"UTC DateTime\",\n    () =&gt; new DateTime(value, DateTimeKind.Utc));\n  TryFormat(\"Local DateTime\",\n    () =&gt; new DateTime(value, DateTimeKind.Local));\n  TryFormat(\"Binary DateTime\",\n    () =&gt; DateTime.FromBinary(value));\n  TryFormat(\"MS-DOS Date\/Time\",\n    () =&gt; DateTimeFromDosDateTime(value));\n  TryFormat(\"OLE Automation Date\/Time\",\n    () =&gt; DateTime.FromOADate(<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2015\/06\/22\/10623021.aspx\">BitConverter.Int64BitsToDouble<\/a>(value)));\n }\n}\n<\/pre>\n<p>Once we have parsed out the command line, we pump the value through all the different conversion functions. Most of them are natively supported by the <code>Date&shy;Time<\/code> structure, but we had to create a few of them manually. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Running through the list.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-45211","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Running through the list.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=45211"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/45211\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=45211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=45211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=45211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}