Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support more fixedoffset tz format #2936

Merged
merged 1 commit into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 26 additions & 15 deletions arrow-array/src/timezone.rs
Expand Up @@ -24,19 +24,24 @@ pub use private::{Tz, TzOffset};

/// Parses a fixed offset of the form "+09:00"
fn parse_fixed_offset(tz: &str) -> Result<FixedOffset, ArrowError> {
if tz.len() != 6 {
return Err(ArrowError::ParseError(format!(
"Invalid timezone \"{}\": Expected format [+-]XX:XX",
tz
)));
let mut parsed = Parsed::new();

if let Ok(fixed_offset) = parse(&mut parsed, tz, StrftimeItems::new("%:z"))
.and_then(|_| parsed.to_fixed_offset())
{
return Ok(fixed_offset);
}

let mut parsed = Parsed::new();
parse(&mut parsed, tz, StrftimeItems::new("%:z"))
if let Ok(fixed_offset) = parse(&mut parsed, tz, StrftimeItems::new("%#z"))
.and_then(|_| parsed.to_fixed_offset())
.map_err(|e| {
ArrowError::ParseError(format!("Invalid timezone \"{}\": {}", tz, e))
})
{
return Ok(fixed_offset);
}

Err(ArrowError::ParseError(format!(
"Invalid timezone \"{}\": Expected format [+-]XX:XX, [+-]XX, or [+-]XXXX",
tz
)))
}

#[cfg(feature = "chrono-tz")]
Expand Down Expand Up @@ -313,13 +318,19 @@ mod tests {
9 * 60 * 60
);

let err = "+9:00".parse::<Tz>().unwrap_err().to_string();
assert!(err.contains("Invalid timezone"), "{}", err);
let tz = "+09".parse::<Tz>().unwrap();
assert_eq!(
tz.offset_from_utc_date(&t).fix().local_minus_utc(),
9 * 60 * 60
);

let err = "+09".parse::<Tz>().unwrap_err().to_string();
assert!(err.contains("Invalid timezone"), "{}", err);
let tz = "+0900".parse::<Tz>().unwrap();
assert_eq!(
tz.offset_from_utc_date(&t).fix().local_minus_utc(),
9 * 60 * 60
);

let err = "+0900".parse::<Tz>().unwrap_err().to_string();
let err = "+9:00".parse::<Tz>().unwrap_err().to_string();
assert!(err.contains("Invalid timezone"), "{}", err);
}
}
12 changes: 10 additions & 2 deletions arrow/src/compute/kernels/temporal.rs
Expand Up @@ -1133,8 +1133,16 @@ mod tests {
fn test_temporal_array_timestamp_hour_with_timezone_without_colon() {
let a = TimestampSecondArray::from(vec![60 * 60 * 10])
.with_timezone("+0100".to_string());
let err = hour(&a).unwrap_err().to_string();
assert!(err.contains("Invalid timezone"), "{}", err);
let b = hour(&a).unwrap();
assert_eq!(11, b.value(0));
}

#[test]
fn test_temporal_array_timestamp_hour_with_timezone_without_minutes() {
let a = TimestampSecondArray::from(vec![60 * 60 * 10])
.with_timezone("+01".to_string());
let b = hour(&a).unwrap();
assert_eq!(11, b.value(0));
}

#[test]
Expand Down