mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-27 10:56:28 +00:00
Sub second time resolution (#6978)
* Add deprecation warnings to recently deprecated procs * Fix bad usage of the times module * Introduce sub second resolution * Fix usage of C's time() * Switch to nanosecond resolution * Make Time & Duration opaque again and fix some errors * Change back to TimeInterval for shorthands * Fix JS test * Fix build error for windows * Undeprecate epochTime * Documentation and minor changes * Lots of bugfixes and doc comments * Attempt to make travis & appveyor green * Fix edge cases for dealing with the local timezone * Workaround JS backend overflow/underflow bug * Use better workaround for not knowing the size of time_t * Use all available timezones for tests * Fix indentation * Add procs for accessing the fractional part of a duration * Order time units from smallest to largest since it makes more sense * Include months and years in `TimeUnit` * Review fix
This commit is contained in:
committed by
Andreas Rumpf
parent
19a1cc914f
commit
f6df2d9956
@@ -37,8 +37,8 @@ var t4 = fromUnix(876124714).utc # Mon 6 Oct 08:58:34 BST 1997
|
||||
t4.checkFormat("M MM MMM MMMM", "10 10 Oct October")
|
||||
|
||||
# Interval tests
|
||||
(t4 - initInterval(years = 2)).checkFormat("yyyy", "1995")
|
||||
(t4 - initInterval(years = 7, minutes = 34, seconds = 24)).checkFormat("yyyy mm ss", "1990 24 10")
|
||||
(t4 - initTimeInterval(years = 2)).checkFormat("yyyy", "1995")
|
||||
(t4 - initTimeInterval(years = 7, minutes = 34, seconds = 24)).checkFormat("yyyy mm ss", "1990 24 10")
|
||||
|
||||
# checking dayOfWeek matches known days
|
||||
doAssert getDayOfWeek(01, mJan, 0000) == dSat
|
||||
@@ -56,32 +56,34 @@ doAssert toUnix(toTime(t4L)) + t4L.utcOffset == toUnix(toTime(t4))
|
||||
|
||||
# adding intervals
|
||||
var
|
||||
a1L = toUnix(toTime(t4L + initInterval(hours = 1))) + t4L.utcOffset
|
||||
a1L = toUnix(toTime(t4L + initTimeInterval(hours = 1))) + t4L.utcOffset
|
||||
a1G = toUnix(toTime(t4)) + 60 * 60
|
||||
doAssert a1L == a1G
|
||||
|
||||
# subtracting intervals
|
||||
a1L = toUnix(toTime(t4L - initInterval(hours = 1))) + t4L.utcOffset
|
||||
a1L = toUnix(toTime(t4L - initTimeInterval(hours = 1))) + t4L.utcOffset
|
||||
a1G = toUnix(toTime(t4)) - (60 * 60)
|
||||
doAssert a1L == a1G
|
||||
|
||||
# add/subtract TimeIntervals and Time/TimeInfo
|
||||
doAssert getTime() - 1.seconds == getTime() - 3.seconds + 2.seconds
|
||||
doAssert getTime() + 65.seconds == getTime() + 1.minutes + 5.seconds
|
||||
doAssert getTime() + 60.minutes == getTime() + 1.hours
|
||||
doAssert getTime() + 24.hours == getTime() + 1.days
|
||||
doAssert getTime() + 13.months == getTime() + 1.years + 1.months
|
||||
var
|
||||
ti1 = getTime() + 1.years
|
||||
ti1 -= 1.years
|
||||
doAssert ti1 == getTime()
|
||||
ti1 += 1.days
|
||||
doAssert ti1 == getTime() + 1.days
|
||||
let now = getTime().utc
|
||||
doAssert now + convert(Seconds, Nanoseconds, 1).nanoseconds == now + 1.seconds
|
||||
doAssert now + 1.weeks == now + 7.days
|
||||
doAssert now - 1.seconds == now - 3.seconds + 2.seconds
|
||||
doAssert now + 65.seconds == now + 1.minutes + 5.seconds
|
||||
doAssert now + 60.minutes == now + 1.hours
|
||||
doAssert now + 24.hours == now + 1.days
|
||||
doAssert now + 13.months == now + 1.years + 1.months
|
||||
var ti1 = now + 1.years
|
||||
ti1 = ti1 - 1.years
|
||||
doAssert ti1 == now
|
||||
ti1 = ti1 + 1.days
|
||||
doAssert ti1 == now + 1.days
|
||||
|
||||
# Bug with adding a day to a Time
|
||||
let day = 24.hours
|
||||
let tomorrow = getTime() + day
|
||||
doAssert tomorrow - getTime() == 60*60*24
|
||||
let tomorrow = now + day
|
||||
doAssert tomorrow - now == initDuration(days = 1)
|
||||
|
||||
# Comparison between Time objects should be detected by compiler
|
||||
# as 'noSideEffect'.
|
||||
@@ -207,8 +209,8 @@ template runTimezoneTests() =
|
||||
let
|
||||
parsedJan = parse("2016-01-05 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz")
|
||||
parsedJul = parse("2016-07-01 04:00:00+01:00", "yyyy-MM-dd HH:mm:sszzz")
|
||||
doAssert toTime(parsedJan) == fromUnix(1451962800)
|
||||
doAssert toTime(parsedJul) == fromUnix(1467342000)
|
||||
doAssert toTime(parsedJan).toUnix == 1451962800
|
||||
doAssert toTime(parsedJul).toUnix == 1467342000
|
||||
|
||||
suite "ttimes":
|
||||
|
||||
@@ -220,7 +222,7 @@ suite "ttimes":
|
||||
|
||||
let orig_tz = getEnv("TZ")
|
||||
var tz_cnt = 0
|
||||
for tz_fn in walkFiles(tz_dir & "/*"):
|
||||
for tz_fn in walkFiles(tz_dir & "/**/*"):
|
||||
if symlinkExists(tz_fn) or tz_fn.endsWith(".tab") or
|
||||
tz_fn.endsWith(".list"):
|
||||
continue
|
||||
@@ -252,19 +254,20 @@ suite "ttimes":
|
||||
var local = fromUnix(1469275200).local
|
||||
var utc = fromUnix(1469275200).utc
|
||||
|
||||
let claimedOffset = local.utcOffset
|
||||
let claimedOffset = initDuration(seconds = local.utcOffset)
|
||||
local.utcOffset = 0
|
||||
check claimedOffset == utc.toTime - local.toTime
|
||||
|
||||
test "issue #5704":
|
||||
putEnv("TZ", "Asia/Seoul")
|
||||
let diff = parse("19700101-000000", "yyyyMMdd-hhmmss").toTime - parse("19000101-000000", "yyyyMMdd-hhmmss").toTime
|
||||
check diff == 2208986872
|
||||
check diff == initDuration(seconds = 2208986872)
|
||||
|
||||
test "issue #6465":
|
||||
putEnv("TZ", "Europe/Stockholm")
|
||||
let dt = parse("2017-03-25 12:00", "yyyy-MM-dd hh:mm")
|
||||
check $(dt + 1.days) == "2017-03-26T12:00:00+02:00"
|
||||
check $(dt + initTimeInterval(days = 1)) == "2017-03-26T12:00:00+02:00"
|
||||
check $(dt + initDuration(days = 1)) == "2017-03-26T13:00:00+02:00"
|
||||
|
||||
test "datetime before epoch":
|
||||
check $fromUnix(-2147483648).utc == "1901-12-13T20:45:52+00:00"
|
||||
@@ -362,12 +365,40 @@ suite "ttimes":
|
||||
|
||||
test "subtract months":
|
||||
var dt = initDateTime(1, mFeb, 2017, 00, 00, 00, utc())
|
||||
check $(dt - 1.months) == "2017-01-01T00:00:00+00:00"
|
||||
check $(dt - initTimeInterval(months = 1)) == "2017-01-01T00:00:00+00:00"
|
||||
dt = initDateTime(15, mMar, 2017, 00, 00, 00, utc())
|
||||
check $(dt - 1.months) == "2017-02-15T00:00:00+00:00"
|
||||
check $(dt - initTimeInterval(months = 1)) == "2017-02-15T00:00:00+00:00"
|
||||
dt = initDateTime(31, mMar, 2017, 00, 00, 00, utc())
|
||||
# This happens due to monthday overflow. It's consistent with Phobos.
|
||||
check $(dt - 1.months) == "2017-03-03T00:00:00+00:00"
|
||||
check $(dt - initTimeInterval(months = 1)) == "2017-03-03T00:00:00+00:00"
|
||||
|
||||
test "duration":
|
||||
let d = initDuration
|
||||
check d(hours = 48) + d(days = 5) == d(weeks = 1)
|
||||
let dt = initDateTime(01, mFeb, 2000, 00, 00, 00, 0, utc()) + d(milliseconds = 1)
|
||||
check dt.nanosecond == convert(Milliseconds, Nanoseconds, 1)
|
||||
check d(seconds = 1, milliseconds = 500) * 2 == d(seconds = 3)
|
||||
check d(seconds = 3) div 2 == d(seconds = 1, milliseconds = 500)
|
||||
check d(milliseconds = 1001).seconds == 1
|
||||
check d(seconds = 1, milliseconds = 500) - d(milliseconds = 1250) ==
|
||||
d(milliseconds = 250)
|
||||
check d(seconds = 1, milliseconds = 1) < d(seconds = 1, milliseconds = 2)
|
||||
check d(seconds = 1) <= d(seconds = 1)
|
||||
check d(seconds = 0) - d(milliseconds = 1500) == d(milliseconds = -1500)
|
||||
check d(milliseconds = -1500) == d(seconds = -1, milliseconds = -500)
|
||||
check d(seconds = -1, milliseconds = 500) == d(milliseconds = -500)
|
||||
|
||||
test "large/small dates":
|
||||
discard initDateTime(1, mJan, -35_000, 12, 00, 00, utc())
|
||||
# with local tz
|
||||
discard initDateTime(1, mJan, -35_000, 12, 00, 00)
|
||||
discard initDateTime(1, mJan, 35_000, 12, 00, 00)
|
||||
# with duration/timeinterval
|
||||
let dt = initDateTime(1, mJan, 35_000, 12, 00, 00, utc()) +
|
||||
initDuration(seconds = 1)
|
||||
check dt.second == 1
|
||||
let dt2 = dt + 35_001.years
|
||||
check $dt2 == "0001-01-01T12:00:01+00:00"
|
||||
|
||||
test "compare datetimes":
|
||||
var dt1 = now()
|
||||
|
||||
Reference in New Issue
Block a user