Skip to content

Commit e7dc97c

Browse files
committed
Add TZ="timezone" support
1 parent 8fa8928 commit e7dc97c

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

src/items/builder.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub struct DateTimeBuilder {
1818
time: Option<time::Time>,
1919
weekday: Option<weekday::Weekday>,
2020
timezone: Option<time::Offset>,
21+
conversion_timezone: Option<time::Offset>,
2122
relative: Vec<relative::Relative>,
2223
}
2324

@@ -98,6 +99,15 @@ impl DateTimeBuilder {
9899
}
99100
}
100101

102+
pub(super) fn set_conversion_timezone(mut self, conversion_timezone: time::Offset) -> Result<Self, &'static str> {
103+
if self.conversion_timezone.is_some() {
104+
Err("TZ= cannot appear more than once")
105+
} else {
106+
self.conversion_timezone = Some(conversion_timezone);
107+
Ok(self)
108+
}
109+
}
110+
101111
pub(super) fn push_relative(mut self, relative: relative::Relative) -> Self {
102112
self.relative.push(relative);
103113
self
@@ -270,6 +280,12 @@ impl DateTimeBuilder {
270280
dt = with_timezone_restore(offset, dt)?;
271281
}
272282

283+
if let Some(mut offset) = self.conversion_timezone {
284+
// Reuse with_timezone_restore with a swapped offset
285+
offset.negative = !offset.negative;
286+
dt = with_timezone_restore(offset, dt)?;
287+
}
288+
273289
Some(dt)
274290
}
275291
}

src/items/conversion_timezone.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// For the full copyright and license information, please view the LICENSE
2+
// file that was distributed with this source code.
3+
4+
use winnow::{ModalResult, Parser};
5+
6+
use super::time;
7+
8+
pub(crate) fn parse(input: &mut &str) -> ModalResult<time::Offset> {
9+
let _ = "tz=\"".parse_next(input)?;
10+
let tz = time::timezone(input);
11+
let _ = "\" ".parse_next(input)?;
12+
return tz
13+
}

src/items/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mod time;
3838
mod timezone;
3939
mod weekday;
4040
mod year;
41+
mod conversion_timezone;
4142

4243
// utility modules
4344
mod builder;
@@ -58,6 +59,7 @@ use crate::ParseDateTimeError;
5859

5960
#[derive(PartialEq, Debug)]
6061
pub(crate) enum Item {
62+
ConversionTimeZone(time::Offset),
6163
Timestamp(f64),
6264
Year(u32),
6365
DateTime(combined::DateTime),
@@ -212,6 +214,11 @@ fn parse_items(input: &mut &str) -> ModalResult<DateTimeBuilder> {
212214
loop {
213215
match parse_item.parse_next(input) {
214216
Ok(item) => match item {
217+
Item::ConversionTimeZone(tz) => {
218+
builder = builder
219+
.set_conversion_timezone(tz)
220+
.map_err(|e| expect_error(input, e))?;
221+
}
215222
Item::Timestamp(ts) => {
216223
builder = builder
217224
.set_timestamp(ts)
@@ -265,6 +272,7 @@ fn parse_item(input: &mut &str) -> ModalResult<Item> {
265272
trace(
266273
"parse_item",
267274
alt((
275+
conversion_timezone::parse.map(Item::ConversionTimeZone),
268276
combined::parse.map(Item::DateTime),
269277
date::parse.map(Item::Date),
270278
time::parse.map(Item::Time),

0 commit comments

Comments
 (0)