try to fix datetime-diff for ms, us, ns (#15537)

# 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
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the
tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
This commit is contained in:
Darren Schroeder 2025-04-10 06:52:11 -05:00 committed by GitHub
parent 70d8163181
commit 29eb109b1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 46 additions and 11 deletions

View File

@ -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
}

View File

@ -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 "