Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/Datetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,29 @@ <h3 id="strptime">

</p>
</div>
<div class="binder">
<a class="anchor" href="#subsecond-nanos">
<h3 id="subsecond-nanos">
subsecond-nanos
</h3>
</a>
<div class="description">
defn
</div>
<p class="sig">
(Fn [Uint64] Int)
</p>
<pre class="args">
(subsecond-nanos t)
</pre>
<p class="doc">
<p>returns the sub-second part of the nanosecond count <code>t</code>,
that is, <code>t</code> modulo one billion.</p>
<p>The reduction is exact over the whole <code>Uint64</code> range, including counts wider
than a C <code>long</code>.</p>

</p>
</div>
<div class="binder">
<a class="anchor" href="#to-ordinal">
<h3 id="to-ordinal">
Expand Down
46 changes: 46 additions & 0 deletions test/time.carp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
; render a Datetime as "YYYY-MM-DD HH:MM:SS" for whole-instant comparisons.
(defn stamp [dt] (fmt "%s %s" &(Datetime.isoformat dt) &(Datetime.isotime dt)))

; parts stay under 2^31: a wider Long literal truncates where C long is 32 bits.
(defn nanos [secs ns]
(let [billion (Uint64.from-long 1000000000l)]
(+ (* (Uint64.from-long secs) billion) (Uint64.from-long ns))))

; n UTF-8 continuation bytes, which decode to no character at all.
(defn conts [n] (String.from-bytes &(Array.replicate n &128b)))

Expand Down Expand Up @@ -669,6 +674,47 @@
&(at-tz 2100 1 1 19 0 0 @&Timezone.utc))
"equal-instant? stays timezone-aware past 2038")

; --- sub-second reduction of a 64-bit clock ---
(assert-equal test
999999999
(Datetime.subsecond-nanos (Uint64.from-long 999999999l))
"subsecond-nanos leaves a count below one second alone")
(assert-equal test
500000000
(Datetime.subsecond-nanos (nanos 1l 500000000l))
"subsecond-nanos drops whole seconds")
(assert-equal test
294967296
(Datetime.subsecond-nanos
(Uint64.bit-shift-left (Uint64.from-long 1l) (Uint64.from-long 32l)))
"subsecond-nanos reduces 2^32")
(assert-equal test
662882507
(Datetime.subsecond-nanos (nanos 1787138980l 662882507l))
"subsecond-nanos reduces a realistic monotonic-clock reading")
(assert-equal test
854775808
(Datetime.subsecond-nanos
(Uint64.bit-shift-left (Uint64.from-long 1l) (Uint64.from-long 63l)))
"subsecond-nanos reduces 2^63")
(assert-equal test
709551615
(Datetime.subsecond-nanos Uint64.MAX)
"subsecond-nanos reduces the largest representable count")

; with no second boundary between the samples, now's nanos sit between them.
(let-do [billion (Uint64.from-long 1000000000l)
a (System.nanotime)
dt (Datetime.now)
b (System.nanotime)
lo (Datetime.subsecond-nanos a)
hi (Datetime.subsecond-nanos b)
ns (Maybe.from @(Datetime.nanoseconds &dt) -1)
spans-a-second? (or (> (- b a) billion) (> lo hi))]
(assert-true test
(or spans-a-second? (and (<= lo ns) (<= ns hi)))
"now reads its nanoseconds off the full-width clock"))

(assert-equal test
&@"00:00:30"
&(Datetime.isotime
Expand Down
11 changes: 10 additions & 1 deletion time.carp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,15 @@ The ISO format is of the form `HH:MM:SS`. The date value is not represented.")
(Maybe.from @(minutes dt) 0)
(Maybe.from @(seconds dt) 0)))

(doc subsecond-nanos "returns the sub-second part of the nanosecond count `t`,
that is, `t` modulo one billion.

The reduction is exact over the whole `Uint64` range, including counts wider
than a C `long`.")
(defn subsecond-nanos [t]
(let [billion (Uint64.from-long 1000000000l)]
(Long.to-int (Uint64.to-long (- t (* (/ t billion) billion))))))

(doc now "returns the `Datetime` representing the current time.

All of the time information is obtained from the operating system directly.")
Expand All @@ -471,7 +480,7 @@ All of the time information is obtained from the operating system directly.")
(Maybe.Just @(TM.tm_hour ct))
(Maybe.Just @(TM.tm_min ct))
(Maybe.Just @(TM.tm_sec ct))
(Maybe.Just (Long.to-int (mod (Uint64.to-long t) 1000000000l)))
(Maybe.Just (subsecond-nanos t))
(Maybe.Just
(Timezone.init @(TM.tm_zone ct)
@(TM.tm_gmtoff ct)
Expand Down