chrono
chrono copied to clipboard
Various fixes for formatting dates with a year outside of 0..=9999
We have a couple of problems when formatting dates with a year outside of 0..=9999.
RFC 2822
Formatting in DateTime::to_rfc2822 panicked with "writing rfc2822 datetime to string should never fail".
- The panic message is now "date outside of defined range for rfc2822".
- I added a new method
DateTime::try_to_rfc2822that can returnNonewhen formatting fails. DateTime::to_rfc2822is deprecated with the notice: "Can panic on years outside of the range 0..=9999. Usetry_to_rfc2822()instead."
Formatting with the RFC2822 formatting item could return a panic in the Display method of DelayedFormat.
- The formatting item can be localized, making it already not fully correct according to RFC 2822. But it is convenient, and we have a dedicated method, so I kept it that way.
- Formatting is extended to support years outside the range defined in RFC 2822 to prevent an error. It is now up to the calling function to ensure the date is in range.
RFC 3339 and ISO 8601
RFC 3339 is not defined for dates with a year outside of 0..=9999. ISO 8601 does support it.
DateTime::to_rfc3339 was a hybrid method, claiming to format a datetime as both valid RFC 3339 and ISO 8601. It would write invalid RFC 3339 strings if the year is out of range, which could not be parsed by DateTime::parse_from_rfc3339.
to_rfc3339now panics on out-of-range dates with "date outside of defined range for rfc3339", just liketo_rfc2822.- A new
try_to_rfc3339can returnNonewhen formatting fails. - A new method
to_iso8601functions exactly asto_rfc3339did, because dates that are out of range for RFC 3339 are still valid ISO 8601. to_rfc3339is deprecated with the notice: "Can panic on years outside of the range 0..=9999. Usetry_to_rfc3339()orto_iso8601instead.". This way when users update chrono to a new version a panic is not silently introduced.
Other RFC 3339 formatting methods:
DateTime::to_rfc3339_optsis redefined to format to an ISO 8601 representation when the year is out of range.- The
RFC3339formatting item is also redefined to format to an ISO 8601 representation when the year is out of range (for the same reasons as theRFC2822formatting item: to not panic inside theDisplayimplementation ofDelayedFormat). - This is the formatting item for
"%+".
ISO 8601 and usually valid RFC 3339 is also the Debug output of DateTime.
We have no parser that can read these out-of-range dates, which is what https://github.com/chronotope/chrono/pull/1143 is for.
Year formatting items
I have updated the documentation of the formatting items YearDiv100, YearMod100, IsoYearDiv100 and IsoYearMod100. The implementation supports formatting dates outside the 0..=9999 range, which is now reflected in the documentation.
I strongly recommend some tests to confirm the panic. It's an important behavior presumption to verify as it has a large affect on the important parts of chrono. e.g.
Thank you for even writing out some test cases.
Codecov Report
Merging #1144 (4bc5075) into 0.4.x (604b92a) will increase coverage by
0.01%. The diff coverage is97.00%.
@@ Coverage Diff @@
## 0.4.x #1144 +/- ##
==========================================
+ Coverage 91.50% 91.52% +0.01%
==========================================
Files 38 38
Lines 17314 17371 +57
==========================================
+ Hits 15844 15898 +54
- Misses 1470 1473 +3
| Files | Coverage Δ | |
|---|---|---|
| src/datetime/tests.rs | 96.84% <100.00%> (+0.04%) |
:arrow_up: |
| src/format/mod.rs | 85.04% <ø> (ø) |
|
| src/lib.rs | 95.62% <100.00%> (+0.03%) |
:arrow_up: |
| src/offset/fixed.rs | 82.35% <100.00%> (ø) |
|
| src/format/formatting.rs | 92.43% <80.00%> (-0.04%) |
:arrow_down: |
| src/datetime/mod.rs | 89.44% <95.23%> (+0.14%) |
:arrow_up: |
:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more
@jtmoon79 Sorry it took so long, thank you for the review!