Skip to content

Commit

Permalink
Never return an error when formatting the RFC2822 item.
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Sep 28, 2023
1 parent bf4de75 commit df5c5f1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 15 deletions.
6 changes: 5 additions & 1 deletion src/datetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,12 @@ impl<Tz: TimeZone> DateTime<Tz> {
/// ```
#[cfg(feature = "alloc")]
pub fn try_to_rfc2822(&self) -> Option<String> {
let naive_local = self.overflowing_naive_local();
if !(0..=9999).contains(&naive_local.year()) {
return None;
}
let mut result = String::with_capacity(32);
write_rfc2822(&mut result, self.overflowing_naive_local(), self.offset.fix()).ok()?;
write_rfc2822(&mut result, naive_local, self.offset.fix()).ok()?;
Some(result)
}

Expand Down
22 changes: 8 additions & 14 deletions src/format/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,24 +599,13 @@ pub(crate) fn write_rfc3339(
.format(w, off)
}

/// Write datetimes like `Tue, 1 Jul 2003 10:52:37 +0200`, same as `%a, %d %b %Y %H:%M:%S %z`
///
/// # Errors
///
/// RFC 2822 is only defined on years 0 through 9999, and this function returns an error on dates
/// outside that range.
/// Write datetimes like `Tue, 1 Jul 2003 10:52:37 +0200`, similar to `%a, %d %b %Y %H:%M:%S %z`.
#[cfg(feature = "alloc")]
pub(crate) fn write_rfc2822(
w: &mut impl Write,
dt: NaiveDateTime,
off: FixedOffset,
) -> fmt::Result {
let year = dt.year();
// RFC2822 is only defined on years 0 through 9999
if !(0..=9999).contains(&year) {
return Err(fmt::Error);
}

let english = default_locale();

w.write_str(short_weekdays(english)[dt.weekday().num_days_from_sunday() as usize])?;
Expand All @@ -630,8 +619,13 @@ pub(crate) fn write_rfc2822(
w.write_char(' ')?;
w.write_str(short_months(english)[dt.month0() as usize])?;
w.write_char(' ')?;
write_hundreds(w, (year / 100) as u8)?;
write_hundreds(w, (year % 100) as u8)?;
let year = dt.year();
if (0..=9999).contains(&year) {
write_hundreds(w, (year / 100) as u8)?;
write_hundreds(w, (year % 100) as u8)?;
} else {
write!(w, "{:04}", year)?;
}
w.write_char(' ')?;

let (hour, min, sec) = dt.time().hms();
Expand Down
4 changes: 4 additions & 0 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ pub enum Fixed {
/// Parsing allows an optional colon.
TimezoneOffsetZ,
/// RFC 2822 date and time syntax. Commonly used for email and MIME date and time.
///
/// This does not always output a strictly valid RFC 2822 string. RFC 2822 is only defined on
/// years 0 through 9999. We format a date outside these ranges anyway to prevent a panic when
/// formatting.
RFC2822,
/// RFC 3339 & ISO 8601 date and time syntax.
///
Expand Down

0 comments on commit df5c5f1

Please sign in to comment.