summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2016-10-22 14:44:21 +0200
committerGitHub <noreply@github.com>2016-10-22 14:44:21 +0200
commitf04999e49f85e182c9e18b6846f212bd0b17aeec (patch)
tree79d317e0791c698f27005215c712a37c65db076c
parentcdd69e951f3861b47f3d71bdf6a9aa09d6575100 (diff)
parentb7232bd425806a64ac0879291f0df06bc1bee1b3 (diff)
downloadNim-f04999e49f85e182c9e18b6846f212bd0b17aeec.tar.gz
Merge pull request #4923 from jdbernard/set-dst-properly-in-times-parse
Fix #4922, bug in times.parse, mishandling DST.
-rw-r--r--lib/pure/times.nim18
-rw-r--r--tests/stdlib/ttime.nim16
2 files changed, 28 insertions, 6 deletions
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index 3e3176ab8..efc1dfa92 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -1248,12 +1248,18 @@ proc parse*(value, layout: string): TimeInfo =
       else:
         parseToken(info, token, value, j)
         token = ""
-  # Reset weekday (might not have been provided and the default may be wrong)
-  # and yearday (is never provided directly and therefore probably wrong)
-  let processed = getLocalTime(toTime(info))
-  info.weekday = processed.weekday
-  info.yearday = processed.yearday
-  return info
+
+  # We are going to process the date to find out if we are in DST, because the
+  # default based on the current time may be wrong. Calling getLocalTime will
+  # set this correctly, but the actual time may be offset from when we called
+  # toTime with a possibly incorrect DST setting, so we are only going to take
+  # the isDST from this result.
+  let correctDST = getLocalTime(toTime(info))
+  info.isDST = correctDST.isDST
+
+  # Now we preocess it again with the correct isDST to correct things like
+  # weekday and yearday.
+  return getLocalTime(toTime(info))
 
 # Leap year calculations are adapted from:
 # http://www.codeproject.com/Articles/7358/Ultra-fast-Algorithms-for-Working-with-Leap-Years
diff --git a/tests/stdlib/ttime.nim b/tests/stdlib/ttime.nim
index b3103b412..065009535 100644
--- a/tests/stdlib/ttime.nim
+++ b/tests/stdlib/ttime.nim
@@ -148,3 +148,19 @@ doAssert milliseconds(1000 * 60 * 60 * 24) == days(1)
 doAssert seconds(60 * 60) == hours(1)
 doAssert seconds(60 * 60 * 24) == days(1)
 doAssert seconds(60 * 60 + 65) == (hours(1) + minutes(1) + seconds(5))
+
+# Bug with parse not setting DST properly if the current local DST differs from
+# the date being parsed. Need to test parse dates both in and out of DST. We
+# are testing that be relying on the fact that tranforming a TimeInfo to a Time
+# and back again will correctly set the DST value. With the incorrect parse
+# behavior this will introduce a one hour offset from the named time and the
+# parsed time if the DST value differs between the current time and the date we
+# are parsing.
+#
+# Unfortunately these tests depend on the locale of the system in which they
+# are run. They will not be meaningful when run in a locale without DST. They
+# also assume that Jan. 1 and Jun. 1 will have differing isDST values.
+let dstT1 = parse("2016-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss")
+let dstT2 = parse("2016-06-01 00:00:00", "yyyy-MM-dd HH:mm:ss")
+doAssert dstT1 == getLocalTime(toTime(dstT1))
+doAssert dstT2 == getLocalTime(toTime(dstT2))