You've already forked parse_datetime
mirror of
https://github.com/uutils/parse_datetime.git
synced 2026-06-10 16:13:15 -07:00
Merge pull request #102 from jfinkels/parse-datetime-with-single-digit-offset
Parse datetimes with single digit timezone offset
This commit is contained in:
+21
-11
@@ -77,6 +77,7 @@ mod format {
|
||||
pub const YYYYMMDDHHMM_UTC_OFFSET: &str = "%Y%m%d%H%MUTC%z";
|
||||
pub const YYYYMMDDHHMM_ZULU_OFFSET: &str = "%Y%m%d%H%MZ%z";
|
||||
pub const YYYYMMDDHHMM_HYPHENATED_OFFSET: &str = "%Y-%m-%d %H:%M %z";
|
||||
pub const YYYYMMDDHHMMSS_HYPHENATED_OFFSET: &str = "%Y-%m-%d %H:%M:%S %#z";
|
||||
pub const YYYYMMDDHHMMS_T_SEP: &str = "%Y-%m-%dT%H:%M:%S";
|
||||
pub const UTC_OFFSET: &str = "UTC%#z";
|
||||
pub const ZULU_OFFSET: &str = "Z%#z";
|
||||
@@ -154,9 +155,16 @@ pub fn parse_datetime_at_date<S: AsRef<str> + Clone>(
|
||||
// similar
|
||||
|
||||
// Formats with offsets don't require NaiveDateTime workaround
|
||||
//
|
||||
// HACK: if the string ends with a single digit preceded by a + or -
|
||||
// sign, then insert a 0 between the sign and the digit to make it
|
||||
// possible for `chrono` to parse it.
|
||||
let pattern = Regex::new(r"([\+-])(\d)$").unwrap();
|
||||
let s = pattern.replace(s.as_ref(), "${1}0${2}");
|
||||
for fmt in [
|
||||
format::YYYYMMDDHHMM_OFFSET,
|
||||
format::YYYYMMDDHHMM_HYPHENATED_OFFSET,
|
||||
format::YYYYMMDDHHMMSS_HYPHENATED_OFFSET,
|
||||
format::YYYYMMDDHHMM_UTC_OFFSET,
|
||||
format::YYYYMMDDHHMM_ZULU_OFFSET,
|
||||
] {
|
||||
@@ -230,16 +238,7 @@ pub fn parse_datetime_at_date<S: AsRef<str> + Clone>(
|
||||
// offsets, so instead we replicate parse_date behaviour by getting
|
||||
// the current date with local, and create a date time string at midnight,
|
||||
// before trying offset suffixes
|
||||
//
|
||||
// HACK: if the string ends with a single digit preceded by a + or -
|
||||
// sign, then insert a 0 between the sign and the digit to make it
|
||||
// possible for `chrono` to parse it.
|
||||
let pattern = Regex::new(r"([\+-])(\d)$").unwrap();
|
||||
let ts = format!(
|
||||
"{}0000{}",
|
||||
date.format("%Y%m%d"),
|
||||
pattern.replace(s.as_ref(), "${1}0${2}")
|
||||
);
|
||||
let ts = format!("{}0000{}", date.format("%Y%m%d"), s);
|
||||
for fmt in [
|
||||
format::UTC_OFFSET,
|
||||
format::ZULU_OFFSET,
|
||||
@@ -370,7 +369,7 @@ mod tests {
|
||||
|
||||
#[cfg(test)]
|
||||
mod offsets {
|
||||
use chrono::Local;
|
||||
use chrono::{Local, NaiveDate};
|
||||
|
||||
use crate::parse_datetime;
|
||||
use crate::ParseDateTimeError;
|
||||
@@ -413,6 +412,17 @@ mod tests {
|
||||
Err(ParseDateTimeError::InvalidInput)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_datetime_with_offset() {
|
||||
let actual = parse_datetime("1997-01-19 08:17:48 +0").unwrap();
|
||||
let expected = NaiveDate::from_ymd_opt(1997, 1, 19)
|
||||
.unwrap()
|
||||
.and_hms_opt(8, 17, 48)
|
||||
.unwrap()
|
||||
.and_utc();
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user