Skip to content

Commit

Permalink
Round seconds to nearest minute when serializing offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Jun 8, 2023
1 parent 30eae93 commit aca386d
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,9 @@ where
&FixedOffset::east_opt(3650).unwrap().with_ymd_and_hms(2014, 7, 24, 12, 34, 6).unwrap()
)
.ok(),
Some(r#""2014-07-24T12:34:06+01:00:50""#.into())
// Seconds are not allowed by RFC 3339, offset should be rounded to the nearest minute.
// In this case +01:01
Some(r#""2014-07-24T12:34:06+01:01""#.into())
);
}

Expand Down
15 changes: 12 additions & 3 deletions src/datetime/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,23 @@ impl<Tz: TimeZone> ser::Serialize for DateTime<Tz> {

impl<'a, Tz: TimeZone> fmt::Display for DisplayModifiedRfc3339<'a, Tz> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Reuse `Debug` impls, which is faster.
// Don't use DateTime::to_rfc3339 because we want to use a more compact
// representation (`Z`) for UTC datetimes.

// Reuse the `Debug` impl of `NaiveDateTime`.
Debug::fmt(&self.inner.naive_local(), f)?;
let offset = (*self.inner.offset()).fix();
// Choose a more compact representation (`Z`) for UTC datetimes.
if Some(offset) == FixedOffset::east_opt(0) {
f.write_char('Z')
} else {
Debug::fmt(&offset, f)
// We do not reuse the `Debug` implementation of `FixedOffset` because that may
// contain seconds, which are not allowed by RFC 3339.
let offset = offset.local_minus_utc();
let (sign, offset) = if offset < 0 { ('-', -offset) } else { ('+', offset) };
let mins = (offset + 59) / 60;
let hour = mins / 60;
let min = mins % 60;
write!(f, "{}{:02}:{:02}", sign, hour, min)
}
}
}
Expand Down

0 comments on commit aca386d

Please sign in to comment.