From e11ecc8266d7345ba553875506d34bdb9ed9106d Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 17 Jan 2020 16:24:44 -0800 Subject: [PATCH] times: toUnixFloat, fromUnixFloat (#13044) --- changelog.md | 2 ++ lib/pure/os.nim | 2 +- lib/pure/times.nim | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index 1c0a8ca6cd48..3838da254a1e 100644 --- a/changelog.md +++ b/changelog.md @@ -53,6 +53,8 @@ - Added `os.normalizePathEnd` for additional path sanitization. +- Added `times.fromUnixFloat,toUnixFloat`, subsecond resolution versions of `fromUnix`,`toUnixFloat`. + ## Library changes - `asyncdispatch.drain` now properly takes into account `selector.hasPendingOperations` diff --git a/lib/pure/os.nim b/lib/pure/os.nim index a329d232a65f..a6b6ccffe3f3 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 b1177bc34e8a..6c8ef46ccc75 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.} =