{"id":2003,"date":"2016-01-04T08:28:40","date_gmt":"2016-01-04T08:28:40","guid":{"rendered":"http:\/\/justthesam.com\/?p=2003"},"modified":"2016-01-04T08:28:40","modified_gmt":"2016-01-04T08:28:40","slug":"swift-gmt-vs-europelondon","status":"publish","type":"post","link":"https:\/\/justthesam.com\/?p=2003","title":{"rendered":"Swift &#8211; GMT vs Europe\/London"},"content":{"rendered":"<p><a href=\"http:\/\/20.166.29.245\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36.png\" rel=\"attachment wp-att-2005\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-2005\" src=\"http:\/\/20.166.29.245\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36-1024x70.png\" alt=\"Test error\" width=\"630\" height=\"43\" srcset=\"https:\/\/justthesam.com\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36-1024x70.png 1024w, https:\/\/justthesam.com\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36-300x20.png 300w, https:\/\/justthesam.com\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36-768x52.png 768w, https:\/\/justthesam.com\/wp-content\/uploads\/2016\/01\/Screen-Shot-2016-01-04-at-07.36.36.png 1260w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/a><\/p>\n<p>I was writing tests in Swift for a time parsing function, and on the way to getting it right, I saw some very confusing error output, as per the screenshot above. In that screenshot I&#8217;ve deliberately broken the test (the times don&#8217;t match) to invoke the red error text, but what&#8217;s interesting is that the error reports 04:02:15 and 04:03:15 instead of the times I actually used &#8211; 04:01 and 04:02 respectively.<\/p>\n<p>When you&#8217;re testing\u00a0time-parsing code, the last thing you want is the test failures giving confusing\/misleading figures so I had to get to the bottom of it.<\/p>\n<p>It turns out that GMT and &#8220;Europe\/London&#8221;\u00a0timezones diverge through history (ignoring daylight savings). In fact, in the year 0 AD they were one minute and fifteen seconds different, and it&#8217;s this discrepancy that was showing up in my tests. Note that it doesn&#8217;t affect the test results themselves &#8211; only the display of NSDate values when there&#8217;s a test failure.<\/p>\n<p>I was constructing test times from NSDateComponents and only specifying day, hour and minute, as that was all that was relevant to the tests. However that left the year defaulting to zero. I was also specifying timezone as\u00a0NSTimeZone(name: &#8220;Europe\/London&#8221;). The error messages from XCode only\u00a0have an NSDate to work with however, which\u00a0doesn&#8217;t have any notion of timezone, so XCode used\u00a0UTC\/GMT\u00a0to format for display. And being year zero dates, the time comes out differently. The simple fix for me was to set the year in the NSDateComponents to 2015 to get everything\u00a0into line.<\/p>\n<p>What would happen if I ran the tests in the summer, when daylight savings is in the effect here in the UK? I&#8217;m not sure, but I might end up with times an hour out, for the same reason.<\/p>\n<p>Here&#8217;s some code you can dump into a playground to demonstrate. The results are even weirder if you use &#8220;Europe\/Paris&#8221; as the timezone, giving &#8220;&#8221;0001-01-01 10:35:39 +0000&#8221; as the output, just nine minutes and twenty-one seconds earlier, rather than the whole hour earlier that one might expect (and that you get if you use 2015).<\/p>\n<pre>\/\/ Demonstrate GMT\/UTC != \"Europe\/London\" in year zero.\nlet ukTimeZone = NSTimeZone(name: \"Europe\/London\")!\nlet ukCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)\nukCalendar?.timeZone = ukTimeZone<\/pre>\n<pre>let dateComponents = NSDateComponents()\n\/\/ Reinstate this to fix things.\n\/\/dateComponents.year = 2015\ndateComponents.hour = 10\ndateComponents.minute = 45\ndateComponents.timeZone = ukTimeZone<\/pre>\n<pre>let date = ukCalendar?.dateFromComponents(dateComponents)\ndate?.debugDescription \/\/ \"0001-01-01 10:46:15 +0000\"<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I was writing tests in Swift for a time parsing function, and on the way to getting it right, I saw some very confusing error output, as per the screenshot above. In that screenshot I&#8217;ve deliberately broken the test (the times don&#8217;t match) to invoke the red error text, but what&#8217;s interesting is that the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,27],"tags":[],"class_list":["post-2003","post","type-post","status-publish","format-standard","hentry","category-programming","category-swift"],"_links":{"self":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts\/2003","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2003"}],"version-history":[{"count":0,"href":"https:\/\/justthesam.com\/index.php?rest_route=\/wp\/v2\/posts\/2003\/revisions"}],"wp:attachment":[{"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justthesam.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}