Skip to content

date/ls: Switch from chrono to jiff #7894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 2, 2025
Merged

Conversation

drinkcat
Copy link
Contributor

@drinkcat drinkcat commented May 7, 2025

jiff handling of timezones makes our life so much easier. Also, jiff provides
a convenient feature to only embed the timezone database when necessary (e.g. Windows).

-rwxr-xr-x 2 drinkcat drinkcat 4828144 Apr 27 13:57 target/release/date ## HEAD
-rwxr-xr-x 2 drinkcat drinkcat 3279432 Apr 28 15:42 target/release/date ## jiff
-rwxr-xr-x 2 drinkcat drinkcat 2949080 Apr 27 13:58 target/release/date ## with #7849

Part of the tests taken from #7597 (@jadijadi FYI), then refactored on top of those to add more test cases.

@BurntSushi thanks for your support!

--

Cross.toml: Install tzdata in container

Linux tests require that now, as we now assume /usr/share/zoneinfo
is present.

test_date: Extend coverage to a lot more timezones

Also test %z/%Z formats.

date: Add more TZ tests

[drinkcat: separated test changes]

ls: switch to lenient formating configuration

ls: Avoid additional String creation/copy in display_date

From code provided in #7852 by @BurntSushi.

Depending on the benchmarks, there is still a small performance
difference (~4%) vs main, but it's seen mostly on small trees
getting printed repeatedly, which is probably not a terribly
interesting use case.

ls: cache recent time threshold in jiff implementation

ls: convert to jiff

Revert "ls: Optimize time formatting"

This reverts commit fc6b896.

This also reverts the change from new to new_lenient, we'll
recover that later as part of the jiff conversion.

date: switch from chrono to jiff

Also adds cargo dependency.

Copy link

github-actions bot commented May 7, 2025

GNU testsuite comparison:

Skipping an intermittent issue tests/timeout/timeout (passes in this run but fails in the 'main' branch)

@sylvestre sylvestre requested a review from Copilot May 9, 2025 08:53
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR switches the time handling in both the date and ls utilities from chrono to jiff to improve timezone handling and offer optional timezone database embedding. Key changes include updated tests for expanded timezone coverage (in test_date.rs), a refactoring of ls’s time formatting logic to remove the legacy TimeStyler in favor of jiff’s API (in ls.rs), and corresponding dependency updates in the Cargo.toml files and related build configurations.

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/by-util/test_date.rs Updated testing of timezone handling with various locales and UTC flags
src/uu/ls/src/ls.rs Refactored time formatting code: removed TimeStyler and updated display_date usage
src/uu/ls/Cargo.toml Added jiff dependency with new features
src/uu/date/src/date.rs Migrated date parsing/formatting from chrono to jiff, with updated error handling
src/uu/date/Cargo.toml Added jiff dependency with appropriate feature flags
Cross.toml Added pre-build step to install tzdata
Cargo.toml Updated global dependencies to include jiff’s libraries
.github/workflows/CICD.yml Removed redundant Cross.toml creation step
Comments suppressed due to low confidence (1)

src/uu/ls/src/ls.rs:2889

  • [nitpick] Now that display_date writes directly to the provided buffer and returns a UResult, its naming might be misleading. Consider renaming it (e.g. to write_date) to clarify that it modifies the buffer in place.
output_display.extend(display_date(md, config, state, &mut output_display)?);

match parse_datetime::parse_datetime(s.as_ref()) {
Ok(date) => {
let timestamp =
Timestamp::new(date.timestamp(), date.timestamp_subsec_nanos() as i32).unwrap();
Copy link
Preview

Copilot AI May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using unwrap() here may lead to a panic if Timestamp::new ever fails. Consider handling the potential error explicitly to make the code more robust.

Suggested change
Timestamp::new(date.timestamp(), date.timestamp_subsec_nanos() as i32).unwrap();
Timestamp::new(date.timestamp(), date.timestamp_subsec_nanos() as i32)?;

Copilot uses AI. Check for mistakes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for once, it might make sense ?! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah, it does make some sort of sense... But:

The suggestion doesn't build:

? couldn't convert the error to (std::string::String, ParseDateTimeError)

The error cannot really happen anyway:

This returns an error if the given components would correspond to an instant outside the supported range. Also, nanosecond is limited to the range -999,999,999..=999,999,999.

So yes, technically I could handle the error and convert it, but since timestamp() and timestamp_subsec_nanos() both come from a good library (jiff), and go into another good library (chrono), I think we can just unwrap.

And we can get rid of this conversion once we switch parse_datetime to jiff (I haven't found time to look into that yet...).

@drinkcat
Copy link
Contributor Author

Rebased, and also cleaned up custom_tz_fmt that's not needed anymore.

I'll try to continue this conversion (maybe will look at parse_datetime next).

Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/misc/stdbuf (passes in this run but fails in the 'main' branch)

drinkcat and others added 10 commits May 29, 2025 14:00
Also adds cargo dependency.
This reverts commit fc6b896.

This also reverts the change from new to new_lenient, we'll
recover that later as part of the jiff conversion.
From code provided in uutils#7852 by @BurntSushi.

Depending on the benchmarks, there is _still_ a small performance
difference (~4%) vs main, but it's seen mostly on small trees
getting printed repeatedly, which is probably not a terribly
interesting use case.
[drinkcat: separated test changes]
Linux tests require that now, as we now assume /usr/share/zoneinfo
is present.
@drinkcat
Copy link
Contributor Author

Rebased. @sylvestre do you think we could go ahead with this part of the conversion? We get the most bang for the buck
with this one: Smaller binary, and correct timezone handling.

I'd like to look into parse_datetime as well, but as you could see, I hit other issues, and spent a silly amount of time trying to figure out what I did wrong -- while the original version was already broken ,-P

Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/timeout/timeout (passes in this run but fails in the 'main' branch)

drinkcat added 2 commits June 1, 2025 19:36
Also, the comment does not fully apply anymore, so we can leave
it more open-ended to figure out how to support locale.
Using the current time requires a bit of care, but it's nice
to have a test that doesn't use a fixed date as input.
Copy link

github-actions bot commented Jun 1, 2025

GNU testsuite comparison:

Skip an intermittent issue tests/timeout/timeout (fails in this run but passes in the 'main' branch)

@cakebaker cakebaker merged commit dfc2e24 into uutils:main Jun 2, 2025
73 of 74 checks passed
@cakebaker
Copy link
Contributor

Good work, thanks!

@sylvestre
Copy link
Contributor

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

date: alphabetic time zone abbreviation (%Z) prints local timezone, not the one specified in TZ
4 participants