From ddf8427e58c8c3cf1dbe6f3022d35cc0917aa031 Mon Sep 17 00:00:00 2001 From: Justin <9146678+brickfrog@users.noreply.github.com> Date: Tue, 2 Jun 2026 12:44:09 -0400 Subject: [PATCH 1/2] feat: add fractional Duration total accessors --- src/pkg.generated.mbti | 3 +++ src/tempo.mbt | 27 +++++++++++++++++++++++++++ src/tempo_test.mbt | 9 +++++++++ 3 files changed, 39 insertions(+) diff --git a/src/pkg.generated.mbti b/src/pkg.generated.mbti index 530726e..6fd5892 100644 --- a/src/pkg.generated.mbti +++ b/src/pkg.generated.mbti @@ -141,11 +141,14 @@ pub struct Duration { pub fn Duration::abs(Self) -> Self pub fn Duration::as_days(Self) -> Int64 pub fn Duration::as_hours(Self) -> Int64 +pub fn Duration::as_hours_f64(Self) -> Double pub fn Duration::as_microseconds(Self) -> Int64 pub fn Duration::as_milliseconds(Self) -> Int64 pub fn Duration::as_minutes(Self) -> Int64 +pub fn Duration::as_minutes_f64(Self) -> Double pub fn Duration::as_nanoseconds(Self) -> Int64 pub fn Duration::as_seconds(Self) -> Int64 +pub fn Duration::as_seconds_f64(Self) -> Double pub fn Duration::as_weeks(Self) -> Int64 pub fn Duration::checked_add(Self, Self) -> Self? pub fn Duration::checked_multiply(Self, Int64) -> Self? diff --git a/src/tempo.mbt b/src/tempo.mbt index 602a130..c02f188 100644 --- a/src/tempo.mbt +++ b/src/tempo.mbt @@ -1916,18 +1916,45 @@ pub fn Duration::as_seconds(self : Duration) -> Int64 { self.nanoseconds / ns_per_sec } +///| +/// Total seconds in this duration as a `Double`. +/// +/// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds +/// (~104 days) lose sub-unit precision. +pub fn Duration::as_seconds_f64(self : Duration) -> Double { + self.nanoseconds.to_double() / 1_000_000_000.0 +} + ///| /// Total whole minutes in this duration (truncated toward zero). pub fn Duration::as_minutes(self : Duration) -> Int64 { self.nanoseconds / ns_per_min } +///| +/// Total minutes in this duration as a `Double`. +/// +/// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds +/// (~104 days) lose sub-unit precision. +pub fn Duration::as_minutes_f64(self : Duration) -> Double { + self.nanoseconds.to_double() / 60_000_000_000.0 +} + ///| /// Total whole hours in this duration (truncated toward zero). pub fn Duration::as_hours(self : Duration) -> Int64 { self.nanoseconds / ns_per_hour } +///| +/// Total hours in this duration as a `Double`. +/// +/// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds +/// (~104 days) lose sub-unit precision. +pub fn Duration::as_hours_f64(self : Duration) -> Double { + self.nanoseconds.to_double() / 3_600_000_000_000.0 +} + ///| /// Total whole days in this duration (truncated toward zero). pub fn Duration::as_days(self : Duration) -> Int64 { diff --git a/src/tempo_test.mbt b/src/tempo_test.mbt index c7bf5bb..363af77 100644 --- a/src/tempo_test.mbt +++ b/src/tempo_test.mbt @@ -2062,6 +2062,15 @@ test "Duration::hours" { assert_eq(d.as_minutes(), 60L) } +///| +test "Duration fractional total accessors" { + assert_eq(@tempo.Duration::milliseconds(1500L).as_seconds_f64(), 1.5) + assert_eq(@tempo.Duration::minutes(90L).as_hours_f64(), 1.5) + assert_eq(@tempo.Duration::seconds(30L).as_minutes_f64(), 0.5) + assert_eq(@tempo.Duration::milliseconds(-1500L).as_seconds_f64(), -1.5) + assert_eq(@tempo.Duration::seconds(0L).as_hours_f64(), 0.0) +} + ///| test "Duration op_add" { let a = @tempo.Duration::seconds(30L) From e4ca75de248322639dd7b669db99ae945e5b327f Mon Sep 17 00:00:00 2001 From: Justin <9146678+brickfrog@users.noreply.github.com> Date: Tue, 2 Jun 2026 12:48:28 -0400 Subject: [PATCH 2/2] fix: reuse Duration unit constants --- src/tempo.mbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tempo.mbt b/src/tempo.mbt index c02f188..0a1d7d3 100644 --- a/src/tempo.mbt +++ b/src/tempo.mbt @@ -1922,7 +1922,7 @@ pub fn Duration::as_seconds(self : Duration) -> Int64 { /// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds /// (~104 days) lose sub-unit precision. pub fn Duration::as_seconds_f64(self : Duration) -> Double { - self.nanoseconds.to_double() / 1_000_000_000.0 + self.nanoseconds.to_double() / ns_per_sec.to_double() } ///| @@ -1937,7 +1937,7 @@ pub fn Duration::as_minutes(self : Duration) -> Int64 { /// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds /// (~104 days) lose sub-unit precision. pub fn Duration::as_minutes_f64(self : Duration) -> Double { - self.nanoseconds.to_double() / 60_000_000_000.0 + self.nanoseconds.to_double() / ns_per_min.to_double() } ///| @@ -1952,7 +1952,7 @@ pub fn Duration::as_hours(self : Duration) -> Int64 { /// `Double` has a ~53-bit mantissa, so magnitudes beyond ~2^53 nanoseconds /// (~104 days) lose sub-unit precision. pub fn Duration::as_hours_f64(self : Duration) -> Double { - self.nanoseconds.to_double() / 3_600_000_000_000.0 + self.nanoseconds.to_double() / ns_per_hour.to_double() } ///|