summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2020-01-17 16:24:44 -0800
committerAndreas Rumpf <rumpf_a@web.de>2020-01-18 01:24:44 +0100
commite11ecc8266d7345ba553875506d34bdb9ed9106d (patch)
treef83e5b131f8a3c839e392389f3c7bc2d03d68e23 /lib/pure
parent5010bc1af5f949535f71c4e4df79ef4dd8545e04 (diff)
downloadNim-e11ecc8266d7345ba553875506d34bdb9ed9106d.tar.gz
times: toUnixFloat, fromUnixFloat (#13044)
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/os.nim2
-rw-r--r--lib/pure/times.nim37
2 files changed, 29 insertions, 10 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index a329d232a..a6b6ccffe 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -112,7 +112,7 @@ proc normalizePathEnd(path: string, trailingSep = false): string =
   result = path
   result.normalizePathEnd(trailingSep)
 
-when (NimMajor, NimMinor) >= (1, 1):
+since((1, 1)):
   export normalizePathEnd
 
 proc joinPath*(head, tail: string): string {.
diff --git a/lib/pure/times.nim b/lib/pure/times.nim
index b1177bc34..6c8ef46cc 100644
--- a/lib/pure/times.nim
+++ b/lib/pure/times.nim
@@ -590,10 +590,33 @@ proc fromUnix*(unix: int64): Time
 
 proc toUnix*(t: Time): int64 {.benign, tags: [], raises: [], noSideEffect.} =
   ## Convert ``t`` to a unix timestamp (seconds since ``1970-01-01T00:00:00Z``).
+  ## See also `toUnixFloat` for subsecond resolution.
   runnableExamples:
     doAssert fromUnix(0).toUnix() == 0
   t.seconds
 
+proc fromUnixFloat(seconds: float): Time {.benign, tags: [], raises: [], noSideEffect.} =
+  ## Convert a unix timestamp in seconds to a `Time`; same as `fromUnix`
+  ## but with subsecond resolution.
+  runnableExamples:
+    doAssert fromUnixFloat(123456.0) == fromUnixFloat(123456)
+    doAssert fromUnixFloat(-123456.0) == fromUnixFloat(-123456)
+  let secs = seconds.floor
+  let nsecs = (seconds - secs) * 1e9
+  initTime(secs.int64, nsecs.NanosecondRange)
+
+proc toUnixFloat(t: Time): float {.benign, tags: [], raises: [].} =
+  ## Same as `toUnix` but using subsecond resolution.
+  runnableExamples:
+    let t = getTime()
+    # `<` because of rounding errors
+    doAssert abs(t.toUnixFloat().fromUnixFloat - t) < initDuration(nanoseconds = 1000)
+  t.seconds.float + t.nanosecond / convert(Seconds, Nanoseconds, 1)
+
+since((1, 1)):
+  export fromUnixFloat
+  export toUnixFloat
+
 proc fromWinTime*(win: int64): Time =
   ## Convert a Windows file time (100-nanosecond intervals since
   ## ``1601-01-01T00:00:00Z``) to a ``Time``.
@@ -2685,14 +2708,12 @@ proc initInterval*(seconds, minutes, hours, days, months, years: int = 0):
   initTimeInterval(0, 0, 0, seconds, minutes, hours, days, 0, months, years)
 
 proc fromSeconds*(since1970: float): Time
-    {.tags: [], raises: [], benign, deprecated.} =
+    {.tags: [], raises: [], benign, deprecated: "Use fromUnixFloat or fromUnix".} =
   ## Takes a float which contains the number of seconds since the unix epoch and
   ## returns a time object.
   ##
   ## **Deprecated since v0.18.0:** use ``fromUnix`` instead
-  let nanos = ((since1970 - since1970.int64.float) *
-    convert(Seconds, Nanoseconds, 1).float).int
-  initTime(since1970.int64, nanos)
+  fromUnixFloat(since1970)
 
 proc fromSeconds*(since1970: int64): Time
     {.tags: [], raises: [], benign, deprecated.} =
@@ -2703,11 +2724,9 @@ proc fromSeconds*(since1970: int64): Time
   fromUnix(since1970)
 
 proc toSeconds*(time: Time): float
-    {.tags: [], raises: [], benign, deprecated.} =
-  ## Returns the time in seconds since the unix epoch.
-  ##
-  ## **Deprecated since v0.18.0:** use ``toUnix`` instead
-  time.seconds.float + time.nanosecond / convert(Seconds, Nanoseconds, 1)
+    {.tags: [], raises: [], benign, deprecated: "Use toUnixFloat or toUnix".} =
+  ## Returns the time in seconds since the unix epoch, with subsecond resolution.
+  toUnixFloat(time)
 
 proc getLocalTime*(time: Time): DateTime
     {.tags: [], raises: [], benign, deprecated.} =