From 29eb109b1e3a990eeddf0b9fb60d4787bbdba8c6 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Thu, 10 Apr 2025 06:52:11 -0500 Subject: [PATCH] try to fix `datetime-diff` for ms, us, ns (#15537) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR tries to fix the datetime-diff custom command so that it includes ms, us, ns. Difference in the banner in 2 separate starts. ### Old ```nushell It's been this long since Nushell's first commit: 5yrs 10months 29days 9hrs 1min 47secs ``` ### New ```nushell It's been this long since Nushell's first commit: 5yrs 10months 29days 9hrs 1min 22secs 49ms 885µs ``` There should be ns above on the new one, not sure why there isn't. It could have something to do with how the banner works but i'll save that for another PR. 🤔 It could be because there are no fractional seconds in the math? `datetime-diff (date now) 2019-05-10T09:59:12-07:00`. However, I'm not sure why `date now` has no nanoseconds. Oh, wait. I think that's because MacOS doesn't have nanosecond precision? ``` ❯ ^date +%s.%N 1744251636.365003000 ``` Closes https://github.com/nushell/nushell/issues/15524 /cc @NotTheDr01ds # User-Facing Changes # Tests + Formatting # After Submitting --- crates/nu-std/std/dt/mod.nu | 50 ++++++++++++++++++++++++++-------- crates/nu-std/tests/test_dt.nu | 7 +++++ 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/crates/nu-std/std/dt/mod.nu b/crates/nu-std/std/dt/mod.nu index 95a2a9cb48..3cf8d0061a 100644 --- a/crates/nu-std/std/dt/mod.nu +++ b/crates/nu-std/std/dt/mod.nu @@ -79,7 +79,7 @@ def borrow-minute [from: record, current: record] { def borrow-second [from: record, current: record] { mut current = $current - $current.nanosecond = $current.nanosecond + 1_000_000_000 + $current.millisecond = $current.millisecond + 1_000 $current.second = $current.second - 1 if $current.second < 0 { $current = (borrow-minute $from $current) @@ -88,19 +88,41 @@ def borrow-second [from: record, current: record] { $current } +def borrow-millisecond [from: record, current: record] { + mut current = $current + $current.microsecond = $current.microsecond + 1_000 + $current.millisecond = $current.millisecond - 1 + if $current.millisecond < 0 { + $current = (borrow-second $from $current) + } + + $current +} + +def borrow-microsecond [from: record, current: record] { + mut current = $current + $current.nanosecond = $current.nanosecond + 1_000 + $current.microsecond = $current.microsecond - 1 + if $current.microsecond < 0 { + $current = (borrow-millisecond $from $current) + } + + $current +} + # Subtract later from earlier datetime and return the unit differences as a record @example "Get the difference between two dates" { - dt datetime-diff 2023-05-07T04:08:45+12:00 2019-05-10T09:59:12-07:00 + dt datetime-diff 2023-05-07T04:08:45.582926123+12:00 2019-05-10T09:59:12.967486456-07:00 } --result { year: 3, month: 11, day: 26, hour: 23, minute: 9, - second: 33, - millisecond: 0, - microsecond: 0, - nanosecond: 0, + second: 32, + millisecond: 615, + microsecond: 439, + nanosecond: 667, } export def datetime-diff [ later: datetime, # a later datetime @@ -149,14 +171,20 @@ export def datetime-diff [ $result = (borrow-minute $from_expanded $result) } - $result.nanosecond = $from_expanded.nanosecond - $to_expanded.nanosecond - if $result.nanosecond < 0 { + $result.millisecond = $from_expanded.millisecond - $to_expanded.millisecond + if $result.millisecond < 0 { $result = (borrow-second $from_expanded $result) } - $result.millisecond = ($result.nanosecond / 1_000_000 | into int) # don't want a float - $result.microsecond = (($result.nanosecond mod 1_000_000) / 1_000 | into int) - $result.nanosecond = ($result.nanosecond mod 1_000 | into int) + $result.microsecond = $from_expanded.microsecond - $to_expanded.microsecond + if $result.microsecond < 0 { + $result = (borrow-millisecond $from_expanded $result) + } + + $result.nanosecond = $from_expanded.nanosecond - $to_expanded.nanosecond + if $result.nanosecond < 0 { + $result = (borrow-microsecond $from_expanded $result) + } $result } diff --git a/crates/nu-std/tests/test_dt.nu b/crates/nu-std/tests/test_dt.nu index 137d7538b1..ca132f35e3 100644 --- a/crates/nu-std/tests/test_dt.nu +++ b/crates/nu-std/tests/test_dt.nu @@ -34,6 +34,13 @@ def earlier_arg_must_be_less_or_equal_later [] { assert error {|| (datetime-diff $t1 $t2)} } +@test +def banner_math_with_ms_us_ns [] { + let t1 = 2023-05-07T04:08:45.582926123+12:00 + let t2 = 2019-05-10T09:59:12.967486456-07:00 + assert equal (datetime-diff $t1 $t2) ({year:3, month:11, day:26, hour:23, minute:9, second:32, millisecond:615, microsecond:439 nanosecond:667}) +} + @test def pp_skips_zeros [] { assert equal (pretty-print-duration {year:1, month:0, day:0, hour:0, minute:0, second:0, millisecond:0, microsecond:0 nanosecond:0}) "1yr "