fallible offset conversion

This commit is contained in:
yuankunzhang
2025-05-20 20:57:25 +08:00
parent cc7c143b21
commit ab91b2b6d7
3 changed files with 35 additions and 11 deletions
+8 -3
View File
@@ -303,7 +303,7 @@ fn with_timezone_restore(
offset: time::Offset,
at: DateTime<FixedOffset>,
) -> Option<DateTime<FixedOffset>> {
let offset: FixedOffset = chrono::FixedOffset::from(offset);
let offset: FixedOffset = chrono::FixedOffset::try_from(offset).ok()?;
let copy = at;
let x = at
.with_timezone(&offset)
@@ -360,7 +360,9 @@ fn at_date_inner(date: Vec<Item>, mut d: DateTime<FixedOffset>) -> Option<DateTi
},
..
}) => {
let offset = offset.map(chrono::FixedOffset::from).unwrap_or(*d.offset());
let offset = offset
.and_then(|o| chrono::FixedOffset::try_from(o).ok())
.unwrap_or(*d.offset());
d = new_date(
year.map(|x| x as i32).unwrap_or(d.year()),
@@ -379,7 +381,10 @@ fn at_date_inner(date: Vec<Item>, mut d: DateTime<FixedOffset>) -> Option<DateTi
second,
offset,
}) => {
let offset = offset.map(chrono::FixedOffset::from).unwrap_or(*d.offset());
let offset = offset
.and_then(|o| chrono::FixedOffset::try_from(o).ok())
.unwrap_or(*d.offset());
d = new_date(
d.year(),
d.month(),
+21 -8
View File
@@ -50,6 +50,8 @@ use winnow::{
ModalResult, Parser,
};
use crate::ParseDateTimeError;
use super::{dec_uint, relative, s};
#[derive(PartialEq, Debug, Clone, Default)]
@@ -95,22 +97,33 @@ impl Offset {
}
}
impl From<Offset> for chrono::FixedOffset {
fn from(
impl TryFrom<Offset> for chrono::FixedOffset {
type Error = ParseDateTimeError;
fn try_from(
Offset {
negative,
hours,
minutes,
}: Offset,
) -> Self {
) -> Result<Self, Self::Error> {
let secs = hours * 3600 + minutes * 60;
if negative {
FixedOffset::west_opt(secs.try_into().expect("secs overflow"))
.expect("timezone overflow")
let offset = if negative {
FixedOffset::west_opt(
secs.try_into()
.map_err(|_| ParseDateTimeError::InvalidInput)?,
)
.ok_or(ParseDateTimeError::InvalidInput)?
} else {
FixedOffset::east_opt(secs.try_into().unwrap()).unwrap()
}
FixedOffset::east_opt(
secs.try_into()
.map_err(|_| ParseDateTimeError::InvalidInput)?,
)
.ok_or(ParseDateTimeError::InvalidInput)?
};
Ok(offset)
}
}
+6
View File
@@ -266,6 +266,12 @@ mod tests {
.and_utc();
assert_eq!(actual, expected);
}
#[test]
fn offset_overflow() {
assert!(parse_datetime("m+12").is_err());
assert!(parse_datetime("24:00").is_err());
}
}
#[cfg(test)]