Skip to content

Commit 9bc611b

Browse files
committed
Add try_to_rfc2822, deprecate to_rfc2822
1 parent 3114597 commit 9bc611b

File tree

6 files changed

+59
-25
lines changed

6 files changed

+59
-25
lines changed

bench/benches/chrono.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ fn bench_datetime_to_rfc2822(c: &mut Criterion) {
5656
.unwrap(),
5757
)
5858
.unwrap();
59-
c.bench_function("bench_datetime_to_rfc2822", |b| b.iter(|| black_box(dt).to_rfc2822()));
59+
c.bench_function("bench_datetime_to_rfc2822", |b| {
60+
b.iter(|| black_box(dt).try_to_rfc2822().unwrap())
61+
});
6062
}
6163

6264
fn bench_datetime_to_rfc3339(c: &mut Criterion) {

src/datetime/mod.rs

+30-5
Original file line numberDiff line numberDiff line change
@@ -619,15 +619,40 @@ impl<Tz: TimeZone> DateTime<Tz> {
619619
///
620620
/// # Panics
621621
///
622-
/// Panics if the date can not be represented in this format: the year may not be negative and
623-
/// can not have more than 4 digits.
622+
/// RFC 2822 is only defined on years 0 through 9999, and this method panics on dates outside
623+
/// of that range.
624624
#[cfg(feature = "alloc")]
625625
#[must_use]
626+
#[deprecated(
627+
since = "0.4.32",
628+
note = "Can panic on years outside of the range 0..=9999. Use `try_to_rfc2822()` instead."
629+
)]
626630
pub fn to_rfc2822(&self) -> String {
631+
self.try_to_rfc2822().expect("date outside of defined range for rfc2822")
632+
}
633+
634+
/// Returns an RFC 2822 date and time string such as `Tue, 1 Jul 2003 10:52:37 +0200`.
635+
///
636+
/// # Errors
637+
///
638+
/// RFC 2822 is only defined on years 0 through 9999, and this method returns an error on dates
639+
/// outside of that range.
640+
///
641+
/// # Example
642+
///
643+
/// ```rust
644+
/// # use chrono::{TimeZone, Utc};
645+
/// let dt = Utc.with_ymd_and_hms(2023, 6, 10, 9, 18, 25).unwrap();
646+
/// assert_eq!(dt.try_to_rfc2822(), Some("Sat, 10 Jun 2023 09:18:25 +0000".to_owned()));
647+
///
648+
/// let dt = Utc.with_ymd_and_hms(10_000, 1, 1, 0, 0, 0).unwrap();
649+
/// assert_eq!(dt.try_to_rfc2822(), None);
650+
/// ```
651+
#[cfg(feature = "alloc")]
652+
pub fn try_to_rfc2822(&self) -> Option<String> {
627653
let mut result = String::with_capacity(32);
628-
write_rfc2822(&mut result, self.overflowing_naive_local(), self.offset.fix())
629-
.expect("writing rfc2822 datetime to string should never fail");
630-
result
654+
write_rfc2822(&mut result, self.overflowing_naive_local(), self.offset.fix()).ok()?;
655+
Some(result)
631656
}
632657

633658
/// Returns an RFC 3339 and ISO 8601 date and time string such as `1996-12-19T16:39:57-08:00`.

src/datetime/tests.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -645,12 +645,12 @@ fn test_datetime_rfc2822() {
645645

646646
// timezone 0
647647
assert_eq!(
648-
Utc.with_ymd_and_hms(2015, 2, 18, 23, 16, 9).unwrap().to_rfc2822(),
649-
"Wed, 18 Feb 2015 23:16:09 +0000"
648+
Utc.with_ymd_and_hms(2015, 2, 18, 23, 16, 9).unwrap().try_to_rfc2822().as_deref(),
649+
Some("Wed, 18 Feb 2015 23:16:09 +0000")
650650
);
651651
assert_eq!(
652-
Utc.with_ymd_and_hms(2015, 2, 1, 23, 16, 9).unwrap().to_rfc2822(),
653-
"Sun, 1 Feb 2015 23:16:09 +0000"
652+
Utc.with_ymd_and_hms(2015, 2, 1, 23, 16, 9).unwrap().try_to_rfc2822().as_deref(),
653+
Some("Sun, 1 Feb 2015 23:16:09 +0000")
654654
);
655655
// timezone +05
656656
assert_eq!(
@@ -661,8 +661,9 @@ fn test_datetime_rfc2822() {
661661
.unwrap()
662662
)
663663
.unwrap()
664-
.to_rfc2822(),
665-
"Wed, 18 Feb 2015 23:16:09 +0500"
664+
.try_to_rfc2822()
665+
.as_deref(),
666+
Some("Wed, 18 Feb 2015 23:16:09 +0500")
666667
);
667668
assert_eq!(
668669
DateTime::parse_from_rfc2822("Wed, 18 Feb 2015 23:59:60 +0500"),
@@ -696,8 +697,9 @@ fn test_datetime_rfc2822() {
696697
.unwrap()
697698
)
698699
.unwrap()
699-
.to_rfc2822(),
700-
"Wed, 18 Feb 2015 23:59:60 +0500"
700+
.try_to_rfc2822()
701+
.as_deref(),
702+
Some("Wed, 18 Feb 2015 23:59:60 +0500")
701703
);
702704

703705
assert_eq!(
@@ -709,8 +711,8 @@ fn test_datetime_rfc2822() {
709711
Ok(FixedOffset::east_opt(0).unwrap().with_ymd_and_hms(2015, 2, 18, 23, 16, 9).unwrap())
710712
);
711713
assert_eq!(
712-
ymdhms_micro(&edt, 2015, 2, 18, 23, 59, 59, 1_234_567).to_rfc2822(),
713-
"Wed, 18 Feb 2015 23:59:60 +0500"
714+
ymdhms_micro(&edt, 2015, 2, 18, 23, 59, 59, 1_234_567).try_to_rfc2822().as_deref(),
715+
Some("Wed, 18 Feb 2015 23:59:60 +0500")
714716
);
715717
assert_eq!(
716718
DateTime::parse_from_rfc2822("Wed, 18 Feb 2015 23:59:58 +0500"),
@@ -1535,8 +1537,8 @@ fn test_min_max_getters() {
15351537
let beyond_max = offset_max.from_utc_datetime(&NaiveDateTime::MAX);
15361538

15371539
assert_eq!(format!("{:?}", beyond_min), "-262144-12-31T22:00:00-02:00");
1538-
// RFC 2822 doesn't support years with more than 4 digits.
1539-
// assert_eq!(beyond_min.to_rfc2822(), "");
1540+
#[cfg(feature = "alloc")]
1541+
assert_eq!(beyond_min.try_to_rfc2822(), None); // doesn't support years with more than 4 digits.
15401542
#[cfg(feature = "alloc")]
15411543
assert_eq!(beyond_min.to_rfc3339(), "-262144-12-31T22:00:00-02:00");
15421544
#[cfg(feature = "alloc")]
@@ -1560,8 +1562,8 @@ fn test_min_max_getters() {
15601562
assert_eq!(beyond_min.nanosecond(), 0);
15611563

15621564
assert_eq!(format!("{:?}", beyond_max), "+262143-01-01T01:59:59.999999999+02:00");
1563-
// RFC 2822 doesn't support years with more than 4 digits.
1564-
// assert_eq!(beyond_max.to_rfc2822(), "");
1565+
#[cfg(feature = "alloc")]
1566+
assert_eq!(beyond_max.try_to_rfc2822(), None); // doesn't support years with more than 4 digits.
15651567
#[cfg(feature = "alloc")]
15661568
assert_eq!(beyond_max.to_rfc3339(), "+262143-01-01T01:59:59.999999999+02:00");
15671569
#[cfg(feature = "alloc")]

src/format/formatting.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -595,8 +595,13 @@ pub(crate) fn write_rfc3339(
595595
.format(w, off)
596596
}
597597

598+
/// Write datetimes like `Tue, 1 Jul 2003 10:52:37 +0200`, same as `%a, %d %b %Y %H:%M:%S %z`
599+
///
600+
/// # Errors
601+
///
602+
/// RFC 2822 is only defined on years 0 through 9999, and this function returns an error on dates
603+
/// outside that range.
598604
#[cfg(feature = "alloc")]
599-
/// write datetimes like `Tue, 1 Jul 2003 10:52:37 +0200`, same as `%a, %d %b %Y %H:%M:%S %z`
600605
pub(crate) fn write_rfc2822(
601606
w: &mut impl Write,
602607
dt: NaiveDateTime,

src/format/parsed.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday};
7272
/// parsed.set_second(40)?;
7373
/// parsed.set_offset(0)?;
7474
/// let dt = parsed.to_datetime()?;
75-
/// assert_eq!(dt.to_rfc2822(), "Wed, 31 Dec 2014 04:26:40 +0000");
75+
/// assert_eq!(dt.try_to_rfc2822().unwrap(), "Wed, 31 Dec 2014 04:26:40 +0000");
7676
///
7777
/// let mut parsed = Parsed::new();
7878
/// parsed.set_weekday(Weekday::Thu)?; // changed to the wrong day
@@ -109,7 +109,7 @@ use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday};
109109
/// parse(&mut parsed, "Wed, 31 Dec 2014 04:26:40 +0000", rfc_2822.iter())?;
110110
/// let dt = parsed.to_datetime()?;
111111
///
112-
/// assert_eq!(dt.to_rfc2822(), "Wed, 31 Dec 2014 04:26:40 +0000");
112+
/// assert_eq!(dt.try_to_rfc2822().unwrap(), "Wed, 31 Dec 2014 04:26:40 +0000");
113113
///
114114
/// let mut parsed = Parsed::new();
115115
/// parse(&mut parsed, "Thu, 31 Dec 2014 04:26:40 +0000", rfc_2822.iter())?;

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@
304304
//!
305305
//! assert_eq!(dt.format("%a %b %e %T %Y").to_string(), dt.format("%c").to_string());
306306
//! assert_eq!(dt.to_string(), "2014-11-28 12:00:09 UTC");
307-
//! assert_eq!(dt.to_rfc2822(), "Fri, 28 Nov 2014 12:00:09 +0000");
307+
//! assert_eq!(dt.try_to_rfc2822().unwrap(), "Fri, 28 Nov 2014 12:00:09 +0000");
308308
//! assert_eq!(dt.to_rfc3339(), "2014-11-28T12:00:09+00:00");
309309
//! assert_eq!(format!("{:?}", dt), "2014-11-28T12:00:09Z");
310310
//!
@@ -396,7 +396,7 @@
396396
//!
397397
//! // Construct a datetime from epoch:
398398
//! let dt: DateTime<Utc> = DateTime::from_timestamp(1_500_000_000, 0).unwrap();
399-
//! assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");
399+
//! assert_eq!(dt.try_to_rfc2822(), Some("Fri, 14 Jul 2017 02:40:00 +0000".to_owned()));
400400
//!
401401
//! // Get epoch value from a datetime:
402402
//! let dt = DateTime::parse_from_rfc2822("Fri, 14 Jul 2017 02:40:00 +0000").unwrap();

0 commit comments

Comments
 (0)