Skip to content

Commit 195e22a

Browse files
committed
Add timezone parsing
1 parent 7ac9a7b commit 195e22a

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

numbat/src/datetime.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,30 @@ pub fn parse_datetime(input: &str) -> Result<Option<DateTime<FixedOffset>>, Pars
4141
];
4242

4343
for format in FORMATS {
44-
// With UTC offset
44+
// Try to match the given format plus an additional UTC offset (%z)
4545
if let Ok(dt) = chrono::DateTime::parse_from_str(input, &format!("{format} %z")) {
4646
return Ok(Some(dt));
4747
}
4848

49-
// Without offset
49+
// Try to match the given format plus an additional timezone name (%Z).
50+
// chrono does not support %Z, so we implement this ourselves. We were
51+
// warned by developers before us not to write timezone-related code on
52+
// our own, so we're probably going to regret this.
53+
54+
// Get the last space-separated word in the input string, and try to parse it
55+
// as a timezone specifier, then try to match the rest of the string with the
56+
// given format.
57+
if let Some((rest, potential_timezone_name)) = input.rsplit_once(' ') {
58+
if let Ok(tz) = potential_timezone_name.parse::<Tz>() {
59+
if let Ok(ndt) = chrono::NaiveDateTime::parse_from_str(rest, format) {
60+
if let LocalResult::Single(dt) = ndt.and_local_timezone(tz) {
61+
return Ok(Some(dt.with_timezone(&local_offset_for_datetime(&dt))));
62+
}
63+
}
64+
}
65+
}
66+
67+
// Without timezone/offset
5068
if let Ok(ndt) = chrono::NaiveDateTime::parse_from_str(input, format) {
5169
if let LocalResult::Single(dt) =
5270
ndt.and_local_timezone(get_local_timezone().unwrap_or(chrono_tz::UTC))

0 commit comments

Comments
 (0)