{"id":1573,"date":"2014-03-07T07:00:00","date_gmt":"2014-03-07T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/03\/07\/converting-from-a-utc-based-systemtime-directly-to-a-local-time-based-systemtime\/"},"modified":"2014-03-07T07:00:00","modified_gmt":"2014-03-07T07:00:00","slug":"converting-from-a-utc-based-systemtime-directly-to-a-local-time-based-systemtime","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140307-00\/?p=1573","title":{"rendered":"Converting from a UTC-based SYSTEMTIME directly to a local-time-based SYSTEMTIME"},"content":{"rendered":"<p>Last year, I presented this commutative diagram<\/p>\n<div style=\"height: 300px;width: 600px;font-size: 15px;text-align: center\">\n<div style=\"width: 0px;height: 0px;overflow: hidden\">   A 2-by-2 grid of boxes.   The top row is labeled FILE&shy;TIME; the bottom row is labeled   SYSTEM&shy;TIME.   The first column is labeled UTC; the second column is labeled Local.   The upper left box   is labeled Get&shy;System&shy;Time&shy;As&shy;File&shy;Time.   There is an outgoing arrow to the right   labeled   File&shy;Time&shy;To&shy;Local&shy;File&shy;Time leading to the box in the   second column labeled None.   There is an outgoing arrow downward labeled   File&shy;Time&shy;To&shy;System&shy;Time   leading to the box in the second row, first column,   labeled Get&shy;System&shy;Time.   From the box in the upper right corner labeled None,   there is an outgoing arrow   downward labeled   File&shy;Time&shy;To&shy;System&shy;Time   leading to the box in the second row, second column,   labeled Get&shy;Local&shy;Time. <\/div>\n<div style=\"height: 30px;width: 130px\">UTC<\/div>\n<div style=\"height: 30px;width: 130px\">Local<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">FILE&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;System&shy;Time&shy;As&shy;File&shy;Time<\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">(None)<\/div>\n<div style=\"text-align: left;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"text-align: right;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">SYSTEM&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;System&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;Local&shy;Time<\/div>\n<div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<div>&darr;<\/div>\n<div>&darr;<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p> I claimed that <a href=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/11\/01\/10462403.aspx\"> there was no function to complete the commutative diagram by connecting the bottom two boxes<\/a>.\n I was wrong, but I&#8217;m going to try to get off on a technicality.\n You can connect the two boxes by calling <code>System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time<\/code> with <code>NULL<\/code> as the time zone parameter, which means &#8220;Use the current time zone.&#8221;<\/p>\n<div style=\"height: 300px;width: 600px;font-size: 15px;text-align: center\">\n<div style=\"width: 0px;height: 0px;overflow: hidden\">   The same diagram as above, but there is a new arrow connecting   Get&shy;System&shy;Time to   Get&shy;Local&shy;Time   labeled System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time. <\/div>\n<div style=\"height: 30px;width: 130px\">UTC<\/div>\n<div style=\"height: 30px;width: 130px\">Local<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">FILE&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;System&shy;Time&shy;As&shy;File&shy;Time<\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">(None)<\/div>\n<div style=\"text-align: left;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"text-align: right;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">SYSTEM&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;System&shy;Time<\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">     System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    Get&shy;Local&shy;Time<\/div>\n<div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<div>&darr;<\/div>\n<div>&darr;<\/div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p> This works here because the time being converted always refers to the current time.\n Here comes the technicality.\n This technique doesn&#8217;t work in general because <code>System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time<\/code> uses the time zone in effect <i>at the time being converted<\/i>, whereas the <code>File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/code> function uses the time zone in effect <i>right now<\/i>. Furthermore, it doesn&#8217;t take into account changes in daylight savings rules that <a href=\"http:\/\/en.wikipedia.org\/wiki\/Daylight_saving_time_in_the_United_States#2005_revision_to_dates_of_observance\"> may have historically been different from the current set of rules<\/a>. (Though this is easily repaired by switching to <code>System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time&shy;Ex<\/code>.) The trick works here because the time we are converting is <i>right now<\/i>.\n In other words, the more general diagram does not commute. Instead, it looks more like this:<\/p>\n<div style=\"height: 300px;width: 600px;font-size: 15px;text-align: center\">\n<div style=\"width: 0px;height: 0px;overflow: hidden\">   Same as before, but this time the boxes are unlabeled,   and the bottom right box is split in two.   The inbound arrow from the left goes to one box and the inbound arrow from the top   goes to another box.   The two halves of the split boxes are marked as not equal. <\/div>\n<div style=\"height: 30px;width: 130px\">UTC<\/div>\n<div style=\"height: 30px;width: 130px\">Local<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">FILE&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    <\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\"><\/div>\n<div style=\"text-align: left;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"text-align: right;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">SYSTEM&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    <\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">     System&shy;Time&shy;To&shy;Tz&shy;Specific&shy;Local&shy;Time&shy;Ex<\/div>\n<div style=\"padding-top: 10px;width: 50px;height: 45px;border: solid black 1px\">    <\/div>\n<div style=\"line-height: 45px;width: 10px;height: 45px\">     &ne;    <\/div>\n<div style=\"padding-top: 10px;width: 50px;height: 45px;border: solid black 1px\">    <\/div>\n<div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<div>&darr;<\/div>\n<div>&darr;<\/div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p> This is why the documentation for <code>File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/code> tells you that if you want to get from the upper left corner to the upper right corner while accounting for daylight saving time relative to the time being converted, then you need to take the long way around.<\/p>\n<p> So what we have is not so much a commutative diagram as a something like covering space: If you start at any box and travel around the diagram, you won&#8217;t necessarily end up where you started. Let&#8217;s start at the upper left corner for the sake of example. <\/p>\n<div style=\"height: 300px;width: 600px;font-size: 15px;text-align: center\">\n<div style=\"width: 0px;height: 0px;overflow: hidden\">   Back to the four-box diagram, with empty boxes.   The arrows follow a clockwise path.   From the upper left, we go to the upper right via File&shy;Time&shy;To&shy;Local&shy;File&shy;Time,   then to the bottom right via File&shy;Time&shy;To&shy;System&shy;Time,   then to the bottom left via Tz&shy;Specific&shy;Local&shy;Time&shy;To&shy;System&shy;Time&shy;Ex,   then back to the upper left via Local&shy;File&shy;Time&shy;To&shy;File&shy;Time. <\/div>\n<div style=\"height: 30px;width: 130px\">UTC<\/div>\n<div style=\"height: 30px;width: 130px\">Local<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">FILE&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    <\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;Local&shy;File&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\"><\/div>\n<div style=\"text-align: left;width: 100px;height: 45px;font-size: 12px\">    System&shy;Time&shy;To&shy;File&shy;Time<\/div>\n<div style=\"text-align: right;width: 100px;height: 45px;font-size: 12px\">    File&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"height: 30px;width: 100px;text-align: right\">SYSTEM&shy;TIME<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    <\/div>\n<div style=\"text-align: center;width: 150px;height: 45px;font-size: 12px\">     Tz&shy;Specific&shy;Local&shy;Time&shy;To&shy;System&shy;Time<\/div>\n<div style=\"padding-top: 10px;width: 130px;height: 45px;border: solid black 1px\">    <\/div>\n<div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<div>&darr;<\/div>\n<div>&darr;<\/div>\n<div style=\"width: 150px;text-align: center\">&rarr;<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p> When you return to the upper left box, you might end up somewhere else, probably an hour ahead of or behind where you started. Each time you take a trip around the diagram, you drift another hour further away. Well, until you hit another daylight saving time changeover point. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last year, I presented this commutative diagram A 2-by-2 grid of boxes. The top row is labeled FILE&shy;TIME; the bottom row is labeled SYSTEM&shy;TIME. The first column is labeled UTC; the second column is labeled Local. The upper left box is labeled Get&shy;System&shy;Time&shy;As&shy;File&shy;Time. There is an outgoing arrow to the right labeled File&shy;Time&shy;To&shy;Local&shy;File&shy;Time leading to [&hellip;]<\/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,108],"class_list":["post-1573","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code","tag-time"],"acf":[],"blog_post_summary":"<p>Last year, I presented this commutative diagram A 2-by-2 grid of boxes. The top row is labeled FILE&shy;TIME; the bottom row is labeled SYSTEM&shy;TIME. The first column is labeled UTC; the second column is labeled Local. The upper left box is labeled Get&shy;System&shy;Time&shy;As&shy;File&shy;Time. There is an outgoing arrow to the right labeled File&shy;Time&shy;To&shy;Local&shy;File&shy;Time leading to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1573","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=1573"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/1573\/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=1573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=1573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=1573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}