summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-04-18 07:22:03 -0700
committerGitHub <noreply@github.com>2020-04-18 16:22:03 +0200
commite3919b658fb6abaf3b58bbf813bed6f59bd4d1c9 (patch)
tree746a0a27a607294903fba643a943a75b0f0b5901
parentd839eb9352a6711fcdee23457605a1fa2e41f7d6 (diff)
downloadNim-e3919b658fb6abaf3b58bbf813bed6f59bd4d1c9.tar.gz
fix https://github.com/nim-lang/RFCs/issues/211: `var a: DateTime` compiles and is usable (#14002) [backport:1.2]
* fix https://github.com/nim-lang/RFCs/issues/211: `var a: DateTime` works
* assertValidDate checks for sentinel month
-rw-r--r--lib/pure/times.nim13
-rw-r--r--tests/stdlib/ttimes.nim15
2 files changed, 25 insertions, 3 deletions
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index b9410e14c..2313afbff 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -260,6 +260,7 @@ type
   Month* = enum ## Represents a month. Note that the enum starts at ``1``,
                 ## so ``ord(month)`` will give the month number in the
                 ## range ``1..12``.
+    # mInvalid = (0, "Invalid") # intentionally left out so `items` works
     mJan = (1, "January")
     mFeb = "February"
     mMar = "March"
@@ -296,7 +297,8 @@ when defined(nimHasStyleChecks):
   {.pop.}
 
 type
-  MonthdayRange* = range[1..31]
+  MonthdayRange* = range[0..31]
+    ## 0 represents an invalid day of the month
   HourRange* = range[0..23]
   MinuteRange* = range[0..59]
   SecondRange* = range[0..60]
@@ -670,7 +672,7 @@ proc getDaysInYear*(year: int): int =
 
 proc assertValidDate(monthday: MonthdayRange, month: Month, year: int)
     {.inline.} =
-  assert monthday <= getDaysInMonth(month, year),
+  assert monthday > 0 and monthday <= getDaysInMonth(month, year),
     $year & "-" & intToStr(ord(month), 2) & "-" & $monthday &
       " is not a valid date"
 
@@ -1576,9 +1578,14 @@ proc `<=`*(a, b: DateTime): bool =
   ## Returns true if ``a`` happened before or at the same time as ``b``.
   return a.toTime <= b.toTime
 
+proc isDefault[T](a: T): bool =
+  system.`==`(a, default(T))
+
 proc `==`*(a, b: DateTime): bool =
   ## Returns true if ``a`` and ``b`` represent the same point in time.
-  return a.toTime == b.toTime
+  if a.isDefault: b.isDefault
+  elif b.isDefault: false
+  else: a.toTime == b.toTime
 
 proc isStaticInterval(interval: TimeInterval): bool =
   interval.years == 0 and interval.months == 0 and
diff --git a/tests/stdlib/ttimes.nim b/tests/stdlib/ttimes.nim
index 60e2ffdbe..a8da15f3d 100644
--- a/tests/stdlib/ttimes.nim
+++ b/tests/stdlib/ttimes.nim
@@ -614,6 +614,21 @@ suite "ttimes":
       doAssert x + between(x, y) == y
       doAssert between(x, y) == 1.months + 1.weeks
 
+  test "default DateTime": # https://github.com/nim-lang/RFCs/issues/211
+    var num = 0
+    for ai in Month: num.inc
+    doAssert num == 12
+
+    var a: DateTime
+    doAssert a == DateTime.default
+    doAssert ($a).len > 0 # no crash
+    doAssert a.month.Month.ord == 0
+    doAssert a.month.Month == cast[Month](0)
+    doAssert a.monthday == 0
+
+    doAssertRaises(AssertionError): discard getDayOfWeek(a.monthday, a.month, a.year)
+    doAssertRaises(AssertionError): discard a.toTime
+
   test "inX procs":
     doAssert initDuration(seconds = 1).inSeconds == 1
     doAssert initDuration(seconds = -1).inSeconds == -1