Stream: contributing

Topic: Utc Internal Representation


view this post on Zulip Luke Boswell (May 03 2023 at 00:35):

We were discussing the internal representation of time, and I suggested we change from U128 to I64 for the internal representation as this was what @Hannes is using for the DateTime lib. I've started looking at updating roc-lang/basic-cli to make this change for Utc.roc and have remembered why I used U128. The Rust library provides nanoseconds with U128 e.g. core::time::Duration::as_nanos(&self) -> u128 and the platform currently measures time at that level of precision. Is this an issue that needs to be resolved? I assume we can always just use Num.toI64 : Int * -> I64 as required. when converting to a DateTime.

view this post on Zulip Richard Feldman (May 03 2023 at 00:37):

interesting, I wonder why they chose that :face_with_raised_eyebrow:

view this post on Zulip Luke Boswell (May 03 2023 at 00:40):

Here is the tracking issue

Duration has historically lacked a way to get the actual number of nanoseconds it contained as a normal Rust type because u64 was of insufficient range, and f64 of insufficient precision. The u128 type solves both issues, so I propose adding an as_nanos function to expose the capability.

view this post on Zulip Richard Feldman (May 03 2023 at 00:41):

looking at https://man7.org/linux/man-pages/man2/clock_gettime.2.html and https://stackoverflow.com/a/471287 it appears that if you get the time in Linux, the answer is specified as:

view this post on Zulip Hannes (May 03 2023 at 00:44):

That's how I've defined duration in my datetime library:

Duration : { seconds : I64, nanoseconds : U32 }

copied from Rust's chrono crate.

view this post on Zulip Richard Feldman (May 03 2023 at 00:45):

so I guess if you're storing seconds as i64 and nanoseconds as i32 then if you want to combine those into one single nanoseconds value, I think you need another 30 bits (1 nanosecond is 1e9 seconds, 2^30 is a little over 1e9)

view this post on Zulip Richard Feldman (May 03 2023 at 00:46):

if nanoseconds is u32 and seconds is i64 then I think putting them together you should be able to just barely fit them both into a single i128 number of nanoseconds unless my math is wrong :sweat_smile:

view this post on Zulip Hannes (May 03 2023 at 01:29):

The maximum value that can be stored is Num.maxI64 seconds + 999_999_999 nanoseconds = 2^63 seconds, which I think is more than Num.maxI128 nanoseconds = (2^127 − 1) nanoseconds
image.png

view this post on Zulip Hannes (May 03 2023 at 01:32):

The way chrono handles this is if you try to convert a duration to nanoseconds that is longer than i64::MAX nanoseconds it returns None

view this post on Zulip Brendan Hansknecht (May 03 2023 at 01:32):

No, it fits: 2^63*10^9+999,999,999 = 9...e+27 and 2^127 = 1...e+38

view this post on Zulip Brendan Hansknecht (May 03 2023 at 01:33):

your result has a negative amount of days because the nanoseconds being subtracted are bigger than the amount of seconds.

view this post on Zulip Brendan Hansknecht (May 03 2023 at 01:35):

They fit with tons of extra space, right? You need only 93 bits. So you have 34 bits to spare.

view this post on Zulip Brendan Hansknecht (May 03 2023 at 01:36):

2^93-(2^63*10^9+999,999,999) = 6.80148277428e+26. So everything fits in the 93 bits if I understand correctly.

view this post on Zulip Hannes (May 03 2023 at 01:37):

Ah, yes, you're correct. I got the right result but interpreted the negative sign wrong!


Last updated: Jul 06 2025 at 12:14 UTC