mirror of
https://github.com/bspeice/dtparse
synced 2024-12-22 12:28:08 -05:00
fix: invalid timezone should return err not panic
1. Enhanced time zone check 2. modify default NaiveDate value set 1970-01-01 not today
This commit is contained in:
parent
081cd7bea0
commit
7867769ecd
45
src/lib.rs
45
src/lib.rs
@ -713,9 +713,12 @@ impl Parser {
|
|||||||
ignoretz: bool,
|
ignoretz: bool,
|
||||||
tzinfos: &HashMap<String, i32>,
|
tzinfos: &HashMap<String, i32>,
|
||||||
) -> ParseResult<(NaiveDateTime, Option<FixedOffset>, Option<Vec<String>>)> {
|
) -> ParseResult<(NaiveDateTime, Option<FixedOffset>, Option<Vec<String>>)> {
|
||||||
let default_date = default.unwrap_or(&Local::now().naive_local()).date();
|
// If default is none, 1970-01-01 00:00:00 as default value is better.
|
||||||
|
let default_date = default
|
||||||
let default_ts = NaiveDateTime::new(default_date, NaiveTime::from_hms_opt(0, 0, 0).unwrap());
|
.unwrap_or(&NaiveDate::default().and_hms_opt(0, 0, 0).unwrap())
|
||||||
|
.date();
|
||||||
|
let default_ts =
|
||||||
|
NaiveDateTime::new(default_date, NaiveTime::from_hms_opt(0, 0, 0).unwrap());
|
||||||
|
|
||||||
let (res, tokens) =
|
let (res, tokens) =
|
||||||
self.parse_with_tokens(timestr, dayfirst, yearfirst, fuzzy, fuzzy_with_tokens)?;
|
self.parse_with_tokens(timestr, dayfirst, yearfirst, fuzzy, fuzzy_with_tokens)?;
|
||||||
@ -840,28 +843,54 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
} else if res.hour.is_some() && (l[i] == "+" || l[i] == "-") {
|
} else if res.hour.is_some() && (l[i] == "+" || l[i] == "-") {
|
||||||
let signal = if l[i] == "+" { 1 } else { -1 };
|
let signal = if l[i] == "+" { 1 } else { -1 };
|
||||||
let len_li = l[i].len();
|
// check next index's length
|
||||||
|
let timezone_len = l[i + 1].len();
|
||||||
|
|
||||||
let mut hour_offset: Option<i32> = None;
|
let mut hour_offset: Option<i32> = None;
|
||||||
let mut min_offset: Option<i32> = None;
|
let mut min_offset: Option<i32> = None;
|
||||||
|
|
||||||
// TODO: check that l[i + 1] is integer?
|
// TODO: check that l[i + 1] is integer?
|
||||||
if len_li == 4 {
|
if timezone_len == 4 {
|
||||||
// -0300
|
// -0300
|
||||||
hour_offset = Some(l[i + 1][..2].parse::<i32>()?);
|
hour_offset = Some(l[i + 1][..2].parse::<i32>()?);
|
||||||
min_offset = Some(l[i + 1][2..4].parse::<i32>()?);
|
min_offset = Some(l[i + 1][2..4].parse::<i32>()?);
|
||||||
} else if i + 2 < len_l && l[i + 2] == ":" {
|
} else if i + 2 < len_l && l[i + 2] == ":" {
|
||||||
// -03:00
|
// -03:00
|
||||||
hour_offset = Some(l[i + 1].parse::<i32>()?);
|
let hour_offset_len = l[i + 1].len();
|
||||||
min_offset = Some(l[i + 3].parse::<i32>()?);
|
// -003:00 need err
|
||||||
|
if hour_offset_len <= 2 {
|
||||||
|
let range_len = min(hour_offset_len, 2);
|
||||||
|
hour_offset = Some(l[i + 1][..range_len].parse::<i32>()?);
|
||||||
|
} else {
|
||||||
|
return Err(ParseError::TimezoneUnsupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if timezone is wrong format like "-03:" just return a Err, should not panic.
|
||||||
|
if i + 3 > l.len() - 1 {
|
||||||
|
return Err(ParseError::TimezoneUnsupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
let min_offset_len = l[i + 3].len();
|
||||||
|
// -09:003 need err
|
||||||
|
if min_offset_len <= 2 {
|
||||||
|
let range_len = min(min_offset_len, 2);
|
||||||
|
min_offset = Some(l[i + 3][..range_len].parse::<i32>()?);
|
||||||
|
} else {
|
||||||
|
return Err(ParseError::TimezoneUnsupported);
|
||||||
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
} else if len_li <= 2 {
|
} else if timezone_len <= 2 {
|
||||||
// -[0]3
|
// -[0]3
|
||||||
let range_len = min(l[i + 1].len(), 2);
|
let range_len = min(l[i + 1].len(), 2);
|
||||||
hour_offset = Some(l[i + 1][..range_len].parse::<i32>()?);
|
hour_offset = Some(l[i + 1][..range_len].parse::<i32>()?);
|
||||||
min_offset = Some(0);
|
min_offset = Some(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// like +09123
|
||||||
|
if hour_offset.is_none() && min_offset.is_none() {
|
||||||
|
return Err(ParseError::TimezoneUnsupported);
|
||||||
|
}
|
||||||
|
|
||||||
res.tzoffset =
|
res.tzoffset =
|
||||||
Some(signal * (hour_offset.unwrap() * 3600 + min_offset.unwrap() * 60));
|
Some(signal * (hour_offset.unwrap() * 3600 + min_offset.unwrap() * 60));
|
||||||
|
|
||||||
|
@ -104,3 +104,67 @@ fn github_45() {
|
|||||||
assert!(parse("/2009/07/").is_err());
|
assert!(parse("/2009/07/").is_err());
|
||||||
assert!(parse("2021-09-").is_err());
|
assert!(parse("2021-09-").is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn github_46() {
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 12:00:00+00:"),
|
||||||
|
Err(ParseError::TimezoneUnsupported)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 12:00:00+09123"),
|
||||||
|
Err(ParseError::TimezoneUnsupported)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 13:00:00+00:003"),
|
||||||
|
Err(ParseError::TimezoneUnsupported)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 13:00:00+009:03"),
|
||||||
|
Err(ParseError::TimezoneUnsupported)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 13:00:00+xx:03"),
|
||||||
|
Err(ParseError::InvalidNumeric(
|
||||||
|
"invalid digit found in string".to_owned()
|
||||||
|
))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse("2000-01-01 13:00:00+00:yz"),
|
||||||
|
Err(ParseError::InvalidNumeric(
|
||||||
|
"invalid digit found in string".to_owned()
|
||||||
|
))
|
||||||
|
);
|
||||||
|
let mut parse_result = parse("2000-01-01 13:00:00+00:03");
|
||||||
|
match parse_result {
|
||||||
|
Ok((dt, offset)) => {
|
||||||
|
assert_eq!(format!("{:?}", dt), "2000-01-01T13:00:00".to_string());
|
||||||
|
assert_eq!(format!("{:?}", offset), "Some(+00:03)".to_string());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
parse_result = parse("2000-01-01 12:00:00+0811");
|
||||||
|
match parse_result {
|
||||||
|
Ok((dt, offset)) => {
|
||||||
|
assert_eq!(format!("{:?}", dt), "2000-01-01T12:00:00".to_string());
|
||||||
|
assert_eq!(format!("{:?}", offset), "Some(+08:11)".to_string());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_result = parse("2000");
|
||||||
|
match parse_result {
|
||||||
|
Ok((dt, offset)) => {
|
||||||
|
assert_eq!(format!("{:?}", dt), "2000-01-01T00:00:00".to_string());
|
||||||
|
assert!(offset.is_none());
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user