Skip to content

Commit 0674254

Browse files
authored
Merge pull request #180 from yuankunzhang/fix-time-offset
fix: time offset can only appear after time or timezone
2 parents 6499842 + 8bebfab commit 0674254

File tree

4 files changed

+20
-50
lines changed

4 files changed

+20
-50
lines changed

src/items/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,17 +311,14 @@ mod tests {
311311

312312
let result = parse(&mut "2025-05-19 +00:00 +01:00");
313313
assert!(result.is_err());
314-
assert!(result
315-
.unwrap_err()
316-
.to_string()
317-
.contains("timezone cannot appear more than once"));
314+
assert!(result.unwrap_err().to_string().contains("unexpected input"));
318315

319316
let result = parse(&mut "m1y");
320317
assert!(result.is_err());
321318
assert!(result
322319
.unwrap_err()
323320
.to_string()
324-
.contains("time offset and timezone are mutually exclusive"));
321+
.contains("timezone cannot appear more than once"));
325322

326323
let result = parse(&mut "2025-05-19 abcdef");
327324
assert!(result.is_err());

src/items/time.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ pub fn parse(input: &mut &str) -> ModalResult<Time> {
157157
/// Also used by the [`combined`](super::combined) module
158158
pub fn iso(input: &mut &str) -> ModalResult<Time> {
159159
alt((
160-
(hour24, timezone).map(|(hour, offset)| Time {
160+
(hour24, timezone_num).map(|(hour, offset)| Time {
161161
hour,
162162
minute: 0,
163163
second: 0.0,
@@ -168,7 +168,7 @@ pub fn iso(input: &mut &str) -> ModalResult<Time> {
168168
_: colon,
169169
minute: minute,
170170
second: opt(preceded(colon, second)).map(|s| s.unwrap_or(0.0)),
171-
offset: opt(timezone)
171+
offset: opt(timezone_num)
172172
}),
173173
))
174174
.parse_next(input)
@@ -244,7 +244,7 @@ fn second(input: &mut &str) -> ModalResult<f64> {
244244
}
245245

246246
pub(crate) fn timezone(input: &mut &str) -> ModalResult<Offset> {
247-
alt((timezone_num, timezone_name_offset)).parse_next(input)
247+
timezone_name_offset.parse_next(input)
248248
}
249249

250250
/// Parse a timezone starting with `+` or `-`
@@ -864,13 +864,25 @@ mod tests {
864864
.expect("expect tests to succeed")
865865
};
866866

867-
assert_eq!("+00:00", make_timezone(&mut "+00:00"));
868-
assert_eq!("+00:00", make_timezone(&mut "+0000"));
869-
assert_eq!("-00:00", make_timezone(&mut "-0000"));
870867
assert_eq!("+00:00", make_timezone(&mut "gmt"));
871868
assert_eq!("+01:00", make_timezone(&mut "a"));
872869
assert_eq!("+00:00", make_timezone(&mut "utc"));
873870
assert_eq!("-02:00", make_timezone(&mut "brst"));
874871
assert_eq!("-03:00", make_timezone(&mut "brt"));
875872
}
873+
874+
#[test]
875+
fn test_timezone_num() {
876+
use super::timezone_num;
877+
let make_timezone = |input: &mut &str| {
878+
timezone_num(input)
879+
.map_err(|e| eprintln!("TEST FAILED AT:\n{e}"))
880+
.map(|offset| format!("{offset}"))
881+
.expect("expect tests to succeed")
882+
};
883+
884+
assert_eq!("+00:00", make_timezone(&mut "+00:00"));
885+
assert_eq!("+00:00", make_timezone(&mut "+0000"));
886+
assert_eq!("-00:00", make_timezone(&mut "-0000"));
887+
}
876888
}

src/lib.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,6 @@ mod tests {
233233
"Z+07:00",
234234
"Z+0700",
235235
"Z+07",
236-
"+07",
237-
"+7",
238236
];
239237

240238
let expected = format!("{}{}", Local::now().format("%Y%m%d"), "0000+0700");
@@ -389,21 +387,6 @@ mod tests {
389387
}
390388
}
391389

392-
#[cfg(test)]
393-
mod timeonly {
394-
use crate::parse_datetime_at_date;
395-
use chrono::{Local, TimeZone};
396-
use std::env;
397-
#[test]
398-
fn test_time_only() {
399-
env::set_var("TZ", "UTC");
400-
let test_date = Local.with_ymd_and_hms(2024, 3, 3, 0, 0, 0).unwrap();
401-
let parsed_time = parse_datetime_at_date(test_date, "9:04:30 PM +0530")
402-
.unwrap()
403-
.timestamp();
404-
assert_eq!(parsed_time, 1709480070);
405-
}
406-
}
407390
/// Used to test example code presented in the README.
408391
mod readme_test {
409392
use crate::parse_datetime;
@@ -470,8 +453,6 @@ mod tests {
470453
"1997-01-01 00:00:00 +0000",
471454
"1997-01-01 00:00:00 +00",
472455
"199701010000 +0000",
473-
"199701010000UTC+0000",
474-
"199701010000Z+0000",
475456
"1997-01-01 00:00 +0000",
476457
"1997-01-01 00:00:00 +0000",
477458
"1997-01-01T00:00:00+0000",
@@ -538,8 +519,6 @@ mod tests {
538519
"1997-01-01 00:00:00 +0000 +1 year",
539520
"1997-01-01 00:00:00 +00 +1 year",
540521
"199701010000 +0000 +1 year",
541-
"199701010000UTC+0000 +1 year",
542-
"199701010000Z+0000 +1 year",
543522
"1997-01-01T00:00:00Z +1 year",
544523
"1997-01-01 00:00 +0000 +1 year",
545524
"1997-01-01 00:00:00 +0000 +1 year",
@@ -602,22 +581,6 @@ mod tests {
602581
}
603582
}
604583

605-
#[test]
606-
fn test_time_only() {
607-
use chrono::{FixedOffset, Local};
608-
std::env::set_var("TZ", "UTC");
609-
610-
let offset = FixedOffset::east_opt(5 * 60 * 60 + 1800).unwrap();
611-
let expected = Local::now()
612-
.date_naive()
613-
.and_hms_opt(21, 4, 30)
614-
.unwrap()
615-
.and_local_timezone(offset)
616-
.unwrap();
617-
let actual = crate::parse_datetime("9:04:30 PM +0530").unwrap();
618-
assert_eq!(actual, expected);
619-
}
620-
621584
#[test]
622585
fn test_weekday_only() {
623586
use chrono::{Datelike, Days, Local, MappedLocalTime, NaiveTime, Weekday};

tests/time.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ fn test_time_correction_with_overflow(#[case] input: &str, #[case] expected: &st
113113
#[case("23:59:59 pm.")]
114114
#[case("23:59:59+24:01")]
115115
#[case("23:59:59-24:01")]
116-
/* TODO: https://github.com/uutils/parse_datetime/issues/166
117116
#[case("10:59am+01")]
118-
*/
119117
#[case("10:59+01pm")]
120118
#[case("23:59:59+00:00:00")]
121119
fn test_time_invalid(#[case] input: &str) {

0 commit comments

Comments
 (0)