Add %-.f to print the shortest exact fraction - #1814
Closed
KannarFr wants to merge 1 commit into
Closed
Conversation
`%.f` rounds a subsecond value up to a whole group of 3, 6 or 9 digits, so half a second prints as `.500`. `to_rfc3339_opts(SecondsFormat::AutoSi, _)` and a derived `Serialize` do the same. There is currently no way to print `.5`, which several ISO 8601 profiles require -- among them Java's `DateTimeFormatter.ISO_OFFSET_DATE_TIME`, so a Rust service cannot reproduce the bytes a JVM peer emits. Trailing zeros in a fraction are padding, so this reuses the `-` modifier the numeric specifiers already take: `%-.f` prints the shortest fraction that is still exact, and nothing at all when the value is zero. `%0.f`, `%_.f` and `%-.3f` remain errors, as before. Parsing is untouched: `Fixed::NanosecondTrimmed` reads exactly like `Fixed::Nanosecond`, since trimming is a property of printing only. Fixes chronotope#165. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #165.
%.frounds a subsecond value up to a whole group of 3, 6 or 9 digits, so half a second prints as.500.to_rfc3339_opts(SecondsFormat::AutoSi, _)and a derivedSerializeonDateTimedo the same. There is currently no way to print.5.Several ISO 8601 profiles require the shortest form. The one that motivated this is Java's
DateTimeFormatter.ISO_OFFSET_DATE_TIME(and circe'sEncoder.encodeOffsetDateTime, which delegates to it): a Rust service replacing a JVM one cannot reproduce the bytes its peer emits, which matters when two implementations' payloads are compared field-by-field during a migration. #165 opens with the same need from X.690/ASN.1.The specifier
The thread stalled on spelling, between
%-.fand%#.f. This implements%-.f, on the reasoning that trailing zeros in a fraction are padding, so the-modifier the numeric specifiers already carry means here exactly what it means everywhere else in chrono.#in C and instd::fmtselects a more decorated form ({:#x},{:#?}), which is the opposite of what is wanted. If the maintainers prefer%#.f, the change is one match arm inStrftimeItems::nextplus an entry inHAVE_ALTERNATES— happy to switch.Behaviour
%.f%-.f0ns500_000_000ns.500.5123_000_000ns.123.12310ns.000000010.000000011ns.000000001.000000001%0.f,%_.f,%-.3fand%-.9fremain errors, exactly as before — onlyPad::Noneon a bare%.fis given a meaning, and the test pins that.Compatibility
Fixedis already#[non_exhaustive], soFixed::NanosecondTrimmedis semver-compatible; this targetsmain.%-.fwas a hard error before this commit.NanosecondTrimmedjoins theNanosecondarm inparse.rsbecause trimming is a property of printing only, and a parser cannot be "trimmed" — so a trimmed fraction and its padded spelling read back to the same instant. The test asserts a print/parse round-trip over the interesting nanosecond values.Not addressed here
SecondsFormathas no trimmed variant, soto_rfc3339_optsstill cannot emit.5. That looked like it belonged with #1736 (Fixed::RFC3339Secs(SecondsFormat)) rather than in this change; say the word and I'll add it.Checks
cargo testwith--features "default unstable-locales rkyv-32 rkyv-validation serde arbitrary", plus--no-default-featureswith each of{},alloc,unstable-locales,alloc,unstable-locales,now;cargo clippy --all-targets -- -D warnings;cargo fmt --check;RUSTDOCFLAGS=-Dwarnings cargo doc --no-deps; andcargo +1.62.0 check --libfor the MSRV.