use arrow2::array::*;
use arrow2::datatypes::TimeUnit;
use arrow2::temporal_conversions;
use arrow2::types::months_days_ns;
use chrono::NaiveDateTime;
#[test]
fn naive() {
let expected = "Timestamp(Nanosecond, None)[1996-12-19 16:39:57, 1996-12-19 13:39:57, None]";
let fmt = "%Y-%m-%dT%H:%M:%S:z";
let array = Utf8Array::<i32>::from_slice([
"1996-12-19T16:39:57-02:00",
"1996-12-19T13:39:57-03:00",
"1996-12-19 13:39:57-03:00", ]);
let r = temporal_conversions::utf8_to_naive_timestamp_ns(&array, fmt);
assert_eq!(format!("{r:?}"), expected);
let fmt = "%Y-%m-%dT%H:%M:%S"; let array = Utf8Array::<i32>::from_slice([
"1996-12-19T16:39:57-02:00",
"1996-12-19T13:39:57-03:00",
"1996-12-19 13:39:57-03:00", ]);
let r = temporal_conversions::utf8_to_naive_timestamp_ns(&array, fmt);
assert_eq!(format!("{r:?}"), expected);
}
#[test]
fn naive_scalar() {
let fmt = "%Y-%m-%dT%H:%M:%S.%9f%z";
let str = "2023-04-07T12:23:34.123456789Z";
let nanos_expected = 1680870214123456789;
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Second);
assert_eq!(r, Some(nanos_expected / 1_000_000_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Millisecond);
assert_eq!(r, Some(nanos_expected / 1_000_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Microsecond);
assert_eq!(r, Some(nanos_expected / 1_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Nanosecond);
assert_eq!(r, Some(nanos_expected));
}
#[test]
fn naive_scalar_no_tz() {
let fmt = "%Y-%m-%dT%H:%M:%S.%9f";
let str = "2023-04-07T12:23:34.123456789";
let nanos_expected = 1680870214123456789;
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Second);
assert_eq!(r, Some(nanos_expected / 1_000_000_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Millisecond);
assert_eq!(r, Some(nanos_expected / 1_000_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Microsecond);
assert_eq!(r, Some(nanos_expected / 1_000));
let r = temporal_conversions::utf8_to_naive_timestamp_scalar(str, fmt, &TimeUnit::Nanosecond);
assert_eq!(r, Some(nanos_expected));
}
#[test]
fn scalar_tz_aware() {
let fmt = "%Y-%m-%dT%H:%M:%S%.f%:z";
let tz = temporal_conversions::parse_offset("-02:00").unwrap();
let str = "2023-04-07T10:23:34.000000000-02:00";
let nanos_expected = 1680870214000000000;
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Second);
assert_eq!(r, Some(nanos_expected / 1_000_000_000));
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Millisecond);
assert_eq!(r, Some(nanos_expected / 1_000_000));
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Microsecond);
assert_eq!(r, Some(nanos_expected / 1_000));
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Nanosecond);
assert_eq!(r, Some(nanos_expected));
}
#[test]
fn scalar_tz_aware_no_timezone() {
let fmt = "%Y-%m-%dT%H:%M:%S%.f";
let tz = temporal_conversions::parse_offset("-02:00").unwrap();
let str = "2023-04-07T10:23:34.000000000-02:00";
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Second);
assert_eq!(r, None);
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Millisecond);
assert_eq!(r, None);
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Microsecond);
assert_eq!(r, None);
let r = temporal_conversions::utf8_to_timestamp_scalar(str, fmt, &tz, &TimeUnit::Nanosecond);
assert_eq!(r, None);
}
#[test]
fn naive_no_tz() {
let expected = "Timestamp(Nanosecond, None)[1996-12-19 16:39:57, 1996-12-19 13:39:57, None]";
let fmt = "%Y-%m-%dT%H:%M:%S"; let array = Utf8Array::<i32>::from_slice([
"1996-12-19T16:39:57",
"1996-12-19T13:39:57",
"1996-12-19 13:39:57", ]);
let r = temporal_conversions::utf8_to_naive_timestamp_ns(&array, fmt);
assert_eq!(format!("{r:?}"), expected);
}
#[test]
fn timestamp_to_datetime() {
let fmt = "%Y-%m-%dT%H:%M:%S.%9f";
let ts = 1680870214123456789;
assert_eq!(
temporal_conversions::timestamp_ms_to_datetime(ts / 1_000_000),
NaiveDateTime::parse_from_str("2023-04-07T12:23:34.123000000", fmt).unwrap()
);
assert_eq!(
temporal_conversions::timestamp_us_to_datetime(ts / 1_000),
NaiveDateTime::parse_from_str("2023-04-07T12:23:34.123456000", fmt).unwrap()
);
assert_eq!(
temporal_conversions::timestamp_ns_to_datetime(ts),
NaiveDateTime::parse_from_str("2023-04-07T12:23:34.123456789", fmt).unwrap()
);
let ts = -15548276987654321;
assert_eq!(
temporal_conversions::timestamp_ms_to_datetime(ts / 1_000_000),
NaiveDateTime::parse_from_str("1969-07-05T01:02:03.013000000", fmt).unwrap()
);
assert_eq!(
temporal_conversions::timestamp_us_to_datetime(ts / 1_000),
NaiveDateTime::parse_from_str("1969-07-05T01:02:03.012346000", fmt).unwrap()
);
assert_eq!(
temporal_conversions::timestamp_ns_to_datetime(ts),
NaiveDateTime::parse_from_str("1969-07-05T01:02:03.012345679", fmt).unwrap()
);
let fmt = "%Y-%m-%dT%H:%M:%S";
let ts = -2209075200000000000;
let expected = NaiveDateTime::parse_from_str("1899-12-31T00:00:00", fmt).unwrap();
assert_eq!(
temporal_conversions::timestamp_ms_to_datetime(ts / 1_000_000),
expected
);
assert_eq!(
temporal_conversions::timestamp_us_to_datetime(ts / 1_000),
expected
);
assert_eq!(temporal_conversions::timestamp_ns_to_datetime(ts), expected);
}
#[test]
fn timestamp_to_negative_datetime() {
let fmt = "%Y-%m-%d %H:%M:%S";
let ts = -63135596800000000;
let expected = NaiveDateTime::parse_from_str("-0031-04-24 22:13:20", fmt).unwrap();
assert_eq!(
temporal_conversions::timestamp_ms_to_datetime(ts / 1_000),
expected
);
assert_eq!(temporal_conversions::timestamp_us_to_datetime(ts), expected);
}
#[test]
fn tz_aware() {
let tz = "-02:00".to_string();
let expected =
"Timestamp(Nanosecond, Some(\"-02:00\"))[1996-12-19 16:39:57 -02:00, 1996-12-19 17:39:57 -02:00, None]";
let fmt = "%Y-%m-%dT%H:%M:%S%.f%:z";
let array = Utf8Array::<i32>::from_slice([
"1996-12-19T16:39:57.0-02:00",
"1996-12-19T16:39:57.0-03:00", "1996-12-19 13:39:57.0-03:00",
]);
let r = temporal_conversions::utf8_to_timestamp_ns(&array, fmt, tz).unwrap();
assert_eq!(format!("{r:?}"), expected);
}
#[test]
fn tz_aware_no_timezone() {
let tz = "-02:00".to_string();
let expected = "Timestamp(Nanosecond, Some(\"-02:00\"))[None, None, None]";
let fmt = "%Y-%m-%dT%H:%M:%S%.f";
let array = Utf8Array::<i32>::from_slice([
"1996-12-19T16:39:57.0",
"1996-12-19T17:39:57.0",
"1996-12-19 13:39:57.0",
]);
let r = temporal_conversions::utf8_to_timestamp_ns(&array, fmt, tz).unwrap();
assert_eq!(format!("{r:?}"), expected);
}
#[test]
fn add_interval_fixed_offset() {
let timestamp = 68086800; let timeunit = TimeUnit::Second;
let timezone = temporal_conversions::parse_offset("+01:00").unwrap();
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(0, 1, 60_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("1972-02-29 02:01:00 +01:00", format!("{r}"));
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(1, 1, 60_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("1972-03-29 02:01:00 +01:00", format!("{r}"));
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(24, 1, 60_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("1974-03-01 02:01:00 +01:00", format!("{r}"));
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(-1, 1, 60_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("1972-01-29 02:01:00 +01:00", format!("{r}"));
}
#[cfg(feature = "chrono-tz")]
#[test]
fn add_interval_timezone() {
let timestamp = 1585440000;
let timeunit = TimeUnit::Second;
let timezone = temporal_conversions::parse_offset_tz("Europe/Lisbon").unwrap();
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(0, 0, 60 * 60 * 1_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("2020-03-29 02:00:00 WEST", format!("{r}"));
let r = temporal_conversions::add_interval(
timestamp,
timeunit,
months_days_ns::new(7, 0, 60 * 60 * 1_000_000_000),
&timezone,
);
let r = temporal_conversions::timestamp_to_datetime(r, timeunit, &timezone);
assert_eq!("2020-10-29 01:00:00 WET", format!("{r}"));
}