summary refs log tree commit diff stats
path: root/tests/stdlib/ttimes.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/stdlib/ttimes.nim')
-rw-r--r--tests/stdlib/ttimes.nim196
1 files changed, 164 insertions, 32 deletions
diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim
index a6ac186cc..4ab3ba581 100644
--- a/tests/stdlib/ttimes.nim
+++ b/tests/stdlib/ttimes.nim
@@ -28,6 +28,12 @@ t.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
 
 t.checkFormat("yyyyMMddhhmmss", "20380119031407")
 
+# issue 7620
+let t7620_am = parse("4/15/2017 12:01:02 AM +0", "M/d/yyyy' 'h:mm:ss' 'tt' 'z", utc())
+t7620_am.checkFormat("M/d/yyyy' 'h:mm:ss' 'tt' 'z", "4/15/2017 12:01:02 AM +0")
+let t7620_pm = parse("4/15/2017 12:01:02 PM +0", "M/d/yyyy' 'h:mm:ss' 'tt' 'z", utc())
+t7620_pm.checkFormat("M/d/yyyy' 'h:mm:ss' 'tt' 'z", "4/15/2017 12:01:02 PM +0")
+
 let t2 = fromUnix(160070789).utc # Mon 27 Jan 16:06:29 GMT 1975
 t2.checkFormat("d dd ddd dddd h hh H HH m mm M MM MMM MMMM s" &
   " ss t tt y yy yyy yyyy yyyyy z zz zzz",
@@ -37,8 +43,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,33 +62,15 @@ 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
-
-# Bug with adding a day to a Time
-let day = 24.hours
-let tomorrow = getTime() + day
-doAssert tomorrow - getTime() == 60*60*24
-
 # Comparison between Time objects should be detected by compiler
 # as 'noSideEffect'.
 proc cmpTimeNoSideEffect(t1: Time, t2: Time): bool {.noSideEffect.} =
@@ -131,6 +119,10 @@ template parseTest(s, f, sExpected: string, ydExpected: int) =
     echo parsed.yearday, " exp: ", ydExpected
   check(parsed.yearday == ydExpected)
 
+template parseTestExcp(s, f: string) =
+  expect ValueError:
+    let parsed = s.parse(f)
+
 template parseTestTimeOnly(s, f, sExpected: string) =
   check sExpected in $s.parse(f, utc())
 
@@ -203,8 +195,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":
 
@@ -216,7 +208,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
@@ -248,19 +240,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"
@@ -277,10 +270,79 @@ suite "ttimes":
     putEnv("TZ", orig_tz)
 
   else:
-    # not on Linux or macosx: run one parseTest only
+    # not on Linux or macosx: run in the local timezone only
     test "parseTest":
       runTimezoneTests()
 
+  test "incorrect inputs: empty string":
+    parseTestExcp("", "yyyy-MM-dd")
+
+  test "incorrect inputs: year":
+    parseTestExcp("20-02-19", "yyyy-MM-dd")
+
+  test "incorrect inputs: month number":
+    parseTestExcp("2018-2-19", "yyyy-MM-dd")
+
+  test "incorrect inputs: month name":
+    parseTestExcp("2018-Fe", "yyyy-MMM-dd")
+
+  test "incorrect inputs: day":
+    parseTestExcp("2018-02-1", "yyyy-MM-dd")
+
+  test "incorrect inputs: day of week":
+    parseTestExcp("2018-Feb-Mo", "yyyy-MMM-ddd")
+
+  test "incorrect inputs: hour":
+    parseTestExcp("2018-02-19 1:30", "yyyy-MM-dd hh:mm")
+
+  test "incorrect inputs: minute":
+    parseTestExcp("2018-02-19 16:3", "yyyy-MM-dd hh:mm")
+
+  test "incorrect inputs: second":
+    parseTestExcp("2018-02-19 16:30:0", "yyyy-MM-dd hh:mm:ss")
+
+  test "incorrect inputs: timezone (z)":
+    parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss z")
+
+  test "incorrect inputs: timezone (zz) 1":
+    parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss zz")
+
+  test "incorrect inputs: timezone (zz) 2":
+    parseTestExcp("2018-02-19 16:30:00 +1", "yyyy-MM-dd hh:mm:ss zz")
+
+  test "incorrect inputs: timezone (zzz) 1":
+    parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss zzz")
+
+  test "incorrect inputs: timezone (zzz) 2":
+    parseTestExcp("2018-02-19 16:30:00 +01:", "yyyy-MM-dd hh:mm:ss zzz")
+
+  test "incorrect inputs: timezone (zzz) 3":
+    parseTestExcp("2018-02-19 16:30:00 +01:0", "yyyy-MM-dd hh:mm:ss zzz")
+
+  test "dynamic timezone":
+    proc staticOffset(offset: int): Timezone =
+      proc zoneInfoFromTz(adjTime: Time): ZonedTime =
+          result.isDst = false
+          result.utcOffset = offset
+          result.adjTime = adjTime
+
+      proc zoneInfoFromUtc(time: Time): ZonedTime =
+          result.isDst = false
+          result.utcOffset = offset
+          result.adjTime = fromUnix(time.toUnix - offset)
+
+      result.name = ""
+      result.zoneInfoFromTz = zoneInfoFromTz
+      result.zoneInfoFromUtc = zoneInfoFromUtc
+
+    let tz = staticOffset(-9000)
+    let dt = initDateTime(1, mJan, 2000, 12, 00, 00, tz)
+    check dt.utcOffset == -9000
+    check dt.isDst == false
+    check $dt == "2000-01-01T12:00:00+02:30"
+    check $dt.utc == "2000-01-01T09:30:00+00:00"
+    check $dt.utc.inZone(tz) == $dt
+
   test "isLeapYear":
     check isLeapYear(2016)
     check (not isLeapYear(2015))
@@ -289,9 +351,79 @@ 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"
\ No newline at end of file
+    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)
+    check initDuration(seconds = 1, nanoseconds = 2) <=
+      initDuration(seconds = 1, nanoseconds = 3)
+    check (initDuration(seconds = 1, nanoseconds = 3) <=
+      initDuration(seconds = 1, nanoseconds = 1)).not
+
+  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()
+    var dt2 = dt1
+    check dt1 == dt2
+    check dt1 <= dt2
+    dt2 = dt2 + 1.seconds
+    check dt1 < dt2
+
+  test "adding/subtracting TimeInterval":
+    # add/subtract TimeIntervals and Time/TimeInfo
+    let now = getTime().utc
+    check now + convert(Seconds, Nanoseconds, 1).nanoseconds == now + 1.seconds
+    check now + 1.weeks == now + 7.days
+    check now - 1.seconds == now - 3.seconds + 2.seconds
+    check now + 65.seconds == now + 1.minutes + 5.seconds
+    check now + 60.minutes == now + 1.hours
+    check now + 24.hours == now + 1.days
+    check now + 13.months == now + 1.years + 1.months
+    check toUnix(fromUnix(0) + 2.seconds) == 2
+    check toUnix(fromUnix(0) - 2.seconds) == -2
+    var ti1 = now + 1.years
+    ti1 = ti1 - 1.years
+    check ti1 == now
+    ti1 = ti1 + 1.days
+    check ti1 == now + 1.days
+
+    # Bug with adding a day to a Time
+    let day = 24.hours
+    let tomorrow = now + day
+    check tomorrow - now == initDuration(days = 1)
+  
+  test "fromWinTime/toWinTime":
+    check 0.fromUnix.toWinTime.fromWinTime.toUnix == 0
+    check (-1).fromWinTime.nanosecond == convert(Seconds, Nanoseconds, 1) - 100
+    check -1.fromWinTime.toWinTime == -1
+    # One nanosecond is discarded due to differences in time resolution
+    check initTime(0, 101).toWinTime.fromWinTime.nanosecond == 100 
\ No newline at end of file