Merge pull request #4923 from jdbernard/set-dst-properly-in-times-parse

Fix #4922, bug in times.parse, mishandling DST.
This commit is contained in:
Dominik Picheta 2016-10-22 14:44:21 +02:00 • committed by GitHub
commit f04999e49f
2 changed files with 28 additions and 6 deletions

View file

@ -1248,12 +1248,18 @@ proc parse*(value, layout: string): TimeInfo =
else: else:
parseToken(info, token, value, j) parseToken(info, token, value, j)
token = "" token = ""
# Reset weekday (might not have been provided and the default may be wrong)
# and yearday (is never provided directly and therefore probably wrong) # We are going to process the date to find out if we are in DST, because the
let processed = getLocalTime(toTime(info)) # default based on the current time may be wrong. Calling getLocalTime will
info.weekday = processed.weekday # set this correctly, but the actual time may be offset from when we called
info.yearday = processed.yearday # toTime with a possibly incorrect DST setting, so we are only going to take
return info # 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: # Leap year calculations are adapted from:
# http://www.codeproject.com/Articles/7358/Ultra-fast-Algorithms-for-Working-with-Leap-Years # http://www.codeproject.com/Articles/7358/Ultra-fast-Algorithms-for-Working-with-Leap-Years

View file

@ -148,3 +148,19 @@ doAssert milliseconds(1000 * 60 * 60 * 24) == days(1)
doAssert seconds(60 * 60) == hours(1) doAssert seconds(60 * 60) == hours(1)
doAssert seconds(60 * 60 * 24) == days(1) doAssert seconds(60 * 60 * 24) == days(1)
doAssert seconds(60 * 60 + 65) == (hours(1) + minutes(1) + seconds(5)) 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))