You've already forked parse_datetime
mirror of
https://github.com/uutils/parse_datetime.git
synced 2026-06-10 16:13:15 -07:00
fix: time offset can only appear after time or timezone
This commit is contained in:
+2
-5
@@ -311,17 +311,14 @@ mod tests {
|
||||
|
||||
let result = parse(&mut "2025-05-19 +00:00 +01:00");
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("timezone cannot appear more than once"));
|
||||
assert!(result.unwrap_err().to_string().contains("unexpected input"));
|
||||
|
||||
let result = parse(&mut "m1y");
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.contains("time offset and timezone are mutually exclusive"));
|
||||
.contains("timezone cannot appear more than once"));
|
||||
|
||||
let result = parse(&mut "2025-05-19 abcdef");
|
||||
assert!(result.is_err());
|
||||
|
||||
+18
-6
@@ -157,7 +157,7 @@ pub fn parse(input: &mut &str) -> ModalResult<Time> {
|
||||
/// Also used by the [`combined`](super::combined) module
|
||||
pub fn iso(input: &mut &str) -> ModalResult<Time> {
|
||||
alt((
|
||||
(hour24, timezone).map(|(hour, offset)| Time {
|
||||
(hour24, timezone_num).map(|(hour, offset)| Time {
|
||||
hour,
|
||||
minute: 0,
|
||||
second: 0.0,
|
||||
@@ -168,7 +168,7 @@ pub fn iso(input: &mut &str) -> ModalResult<Time> {
|
||||
_: colon,
|
||||
minute: minute,
|
||||
second: opt(preceded(colon, second)).map(|s| s.unwrap_or(0.0)),
|
||||
offset: opt(timezone)
|
||||
offset: opt(timezone_num)
|
||||
}),
|
||||
))
|
||||
.parse_next(input)
|
||||
@@ -244,7 +244,7 @@ fn second(input: &mut &str) -> ModalResult<f64> {
|
||||
}
|
||||
|
||||
pub(crate) fn timezone(input: &mut &str) -> ModalResult<Offset> {
|
||||
alt((timezone_num, timezone_name_offset)).parse_next(input)
|
||||
timezone_name_offset.parse_next(input)
|
||||
}
|
||||
|
||||
/// Parse a timezone starting with `+` or `-`
|
||||
@@ -864,13 +864,25 @@ mod tests {
|
||||
.expect("expect tests to succeed")
|
||||
};
|
||||
|
||||
assert_eq!("+00:00", make_timezone(&mut "+00:00"));
|
||||
assert_eq!("+00:00", make_timezone(&mut "+0000"));
|
||||
assert_eq!("-00:00", make_timezone(&mut "-0000"));
|
||||
assert_eq!("+00:00", make_timezone(&mut "gmt"));
|
||||
assert_eq!("+01:00", make_timezone(&mut "a"));
|
||||
assert_eq!("+00:00", make_timezone(&mut "utc"));
|
||||
assert_eq!("-02:00", make_timezone(&mut "brst"));
|
||||
assert_eq!("-03:00", make_timezone(&mut "brt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timezone_num() {
|
||||
use super::timezone_num;
|
||||
let make_timezone = |input: &mut &str| {
|
||||
timezone_num(input)
|
||||
.map_err(|e| eprintln!("TEST FAILED AT:\n{e}"))
|
||||
.map(|offset| format!("{offset}"))
|
||||
.expect("expect tests to succeed")
|
||||
};
|
||||
|
||||
assert_eq!("+00:00", make_timezone(&mut "+00:00"));
|
||||
assert_eq!("+00:00", make_timezone(&mut "+0000"));
|
||||
assert_eq!("-00:00", make_timezone(&mut "-0000"));
|
||||
}
|
||||
}
|
||||
|
||||
-37
@@ -233,8 +233,6 @@ mod tests {
|
||||
"Z+07:00",
|
||||
"Z+0700",
|
||||
"Z+07",
|
||||
"+07",
|
||||
"+7",
|
||||
];
|
||||
|
||||
let expected = format!("{}{}", Local::now().format("%Y%m%d"), "0000+0700");
|
||||
@@ -389,21 +387,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod timeonly {
|
||||
use crate::parse_datetime_at_date;
|
||||
use chrono::{Local, TimeZone};
|
||||
use std::env;
|
||||
#[test]
|
||||
fn test_time_only() {
|
||||
env::set_var("TZ", "UTC");
|
||||
let test_date = Local.with_ymd_and_hms(2024, 3, 3, 0, 0, 0).unwrap();
|
||||
let parsed_time = parse_datetime_at_date(test_date, "9:04:30 PM +0530")
|
||||
.unwrap()
|
||||
.timestamp();
|
||||
assert_eq!(parsed_time, 1709480070);
|
||||
}
|
||||
}
|
||||
/// Used to test example code presented in the README.
|
||||
mod readme_test {
|
||||
use crate::parse_datetime;
|
||||
@@ -470,8 +453,6 @@ mod tests {
|
||||
"1997-01-01 00:00:00 +0000",
|
||||
"1997-01-01 00:00:00 +00",
|
||||
"199701010000 +0000",
|
||||
"199701010000UTC+0000",
|
||||
"199701010000Z+0000",
|
||||
"1997-01-01 00:00 +0000",
|
||||
"1997-01-01 00:00:00 +0000",
|
||||
"1997-01-01T00:00:00+0000",
|
||||
@@ -538,8 +519,6 @@ mod tests {
|
||||
"1997-01-01 00:00:00 +0000 +1 year",
|
||||
"1997-01-01 00:00:00 +00 +1 year",
|
||||
"199701010000 +0000 +1 year",
|
||||
"199701010000UTC+0000 +1 year",
|
||||
"199701010000Z+0000 +1 year",
|
||||
"1997-01-01T00:00:00Z +1 year",
|
||||
"1997-01-01 00:00 +0000 +1 year",
|
||||
"1997-01-01 00:00:00 +0000 +1 year",
|
||||
@@ -602,22 +581,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_time_only() {
|
||||
use chrono::{FixedOffset, Local};
|
||||
std::env::set_var("TZ", "UTC");
|
||||
|
||||
let offset = FixedOffset::east_opt(5 * 60 * 60 + 1800).unwrap();
|
||||
let expected = Local::now()
|
||||
.date_naive()
|
||||
.and_hms_opt(21, 4, 30)
|
||||
.unwrap()
|
||||
.and_local_timezone(offset)
|
||||
.unwrap();
|
||||
let actual = crate::parse_datetime("9:04:30 PM +0530").unwrap();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_weekday_only() {
|
||||
use chrono::{Datelike, Days, Local, MappedLocalTime, NaiveTime, Weekday};
|
||||
|
||||
@@ -113,9 +113,7 @@ fn test_time_correction_with_overflow(#[case] input: &str, #[case] expected: &st
|
||||
#[case("23:59:59 pm.")]
|
||||
#[case("23:59:59+24:01")]
|
||||
#[case("23:59:59-24:01")]
|
||||
/* TODO: https://github.com/uutils/parse_datetime/issues/166
|
||||
#[case("10:59am+01")]
|
||||
*/
|
||||
#[case("10:59+01pm")]
|
||||
#[case("23:59:59+00:00:00")]
|
||||
fn test_time_invalid(#[case] input: &str) {
|
||||
|
||||
Reference in New Issue
Block a user