This is an automated email from the ASF dual-hosted git repository.
tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/master by this push:
new 409bb81a69 [fix #5044] Support converting 'yyyymmdd' format to date
(#5078)
409bb81a69 is described below
commit 409bb81a69f3ea1b354fa209a5b6b9d54ea06419
Author: Reilly.tang <[email protected]>
AuthorDate: Mon Nov 27 18:37:38 2023 +0800
[fix #5044] Support converting 'yyyymmdd' format to date (#5078)
Signed-off-by: tangruilin <[email protected]>
---
arrow-cast/src/cast.rs | 24 ++++++++++++++++++++++++
arrow-cast/src/parse.rs | 14 +++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/arrow-cast/src/cast.rs b/arrow-cast/src/cast.rs
index 22faedb96f..3d9d0ee3d9 100644
--- a/arrow-cast/src/cast.rs
+++ b/arrow-cast/src/cast.rs
@@ -4879,6 +4879,30 @@ mod tests {
}
}
+ #[test]
+ fn test_cast_string_format_yyyymmdd_to_date32() {
+ let a = Arc::new(StringArray::from(vec![
+ Some("2020-12-25"),
+ Some("20201117"),
+ ])) as ArrayRef;
+
+ let to_type = DataType::Date32;
+ let options = CastOptions {
+ safe: false,
+ format_options: FormatOptions::default(),
+ };
+ let result = cast_with_options(&a, &to_type, &options).unwrap();
+ let c = result.as_primitive::<Date32Type>();
+ assert_eq!(
+ chrono::NaiveDate::from_ymd_opt(2020, 12, 25),
+ c.value_as_date(0)
+ );
+ assert_eq!(
+ chrono::NaiveDate::from_ymd_opt(2020, 11, 17),
+ c.value_as_date(1)
+ );
+ }
+
#[test]
fn test_cast_string_to_time32second() {
let a1 = Arc::new(StringArray::from(vec![
diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs
index f01b2b4c0d..750f38006d 100644
--- a/arrow-cast/src/parse.rs
+++ b/arrow-cast/src/parse.rs
@@ -559,8 +559,20 @@ fn parse_date(string: &str) -> Option<NaiveDate> {
const HYPHEN: u8 = b'-'.wrapping_sub(b'0');
+ // refer to https://www.rfc-editor.org/rfc/rfc3339#section-3
if digits[4] != HYPHEN {
- return None;
+ let (year, month, day) = match (mask, string.len()) {
+ (0b11111111, 8) => (
+ digits[0] as u16 * 1000
+ + digits[1] as u16 * 100
+ + digits[2] as u16 * 10
+ + digits[3] as u16,
+ digits[4] * 10 + digits[5],
+ digits[6] * 10 + digits[7],
+ ),
+ _ => return None,
+ };
+ return NaiveDate::from_ymd_opt(year as _, month as _, day as _);
}
let (month, day) = match mask {