#![allow(clippy::all, clippy::pedantic, clippy::restriction, warnings)]
#[cfg(all(feature = "chrono", feature = "jiff-tz"))]
mod tests {
use chrono::{
DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, TimeZone as ChronoTimeZone,
};
use deep_time::civil_parts::Parts;
#[test]
fn test_to_chrono_naive_datetime_basic_ymd_hms() {
let parsed = Parts::from_str(
"%Y-%m-%d %H:%M:%S",
"2024-04-15 14:30:45",
false,
false,
false,
)
.unwrap();
let ndt = parsed.to_chrono_naive_datetime().unwrap();
let expected_date = NaiveDate::from_ymd_opt(2024, 4, 15).unwrap();
let expected_time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
let expected = expected_date.and_time(expected_time);
assert_eq!(ndt, expected);
}
#[test]
fn test_to_chrono_naive_datetime_ordinal_date() {
let parsed =
Parts::from_str("%Y-%j %H:%M:%S", "2024-106 14:30:45", false, false, false).unwrap();
let ndt = parsed.to_chrono_naive_datetime().unwrap();
let expected_date = NaiveDate::from_yo_opt(2024, 106).unwrap();
let expected_time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
let expected = expected_date.and_time(expected_time);
assert_eq!(ndt, expected);
}
#[test]
fn test_to_chrono_naive_datetime_iso_week_date() {
use chrono::Weekday as ChronoWeekday;
let parsed = Parts::from_str(
"%G-W%V-%u %H:%M:%S",
"2024-W16-2 14:30:45",
false,
false,
false,
)
.unwrap();
let ndt = parsed.to_chrono_naive_datetime().unwrap();
let expected_date = NaiveDate::from_isoywd_opt(2024, 16, ChronoWeekday::Tue).unwrap();
let expected_time = NaiveTime::from_hms_opt(14, 30, 45).unwrap();
let expected = expected_date.and_time(expected_time);
assert_eq!(ndt, expected);
}
#[test]
fn test_to_chrono_naive_datetime_fractional_seconds() {
let parsed = Parts::from_str(
"%Y-%m-%d %H:%M:%S.%N",
"2024-04-15 14:30:45.123456789012345678901234567890",
false,
false,
false,
)
.unwrap();
let ndt = parsed.to_chrono_naive_datetime().unwrap();
let expected_date = NaiveDate::from_ymd_opt(2024, 4, 15).unwrap();
let expected_time = NaiveTime::from_hms_nano_opt(14, 30, 45, 123_456_789).unwrap();
let expected = expected_date.and_time(expected_time);
assert_eq!(ndt, expected);
}
#[test]
fn test_to_chrono_naive_datetime_leap_second() {
let parsed = Parts::from_str(
"%Y-%m-%d %H:%M:%S",
"2024-04-15 23:59:60",
false,
false,
false,
)
.unwrap();
let ndt = parsed.to_chrono_naive_datetime().unwrap();
let expected_date = NaiveDate::from_ymd_opt(2024, 4, 15).unwrap();
let expected_time = NaiveTime::from_hms_nano_opt(23, 59, 59, 1_000_000_000).unwrap();
let expected = expected_date.and_time(expected_time);
assert_eq!(ndt, expected);
}
#[test]
fn test_to_chrono_datetime_fixed_offset() {
let parsed =
Parts::from_str("%F %T %z", "2024-04-15 14:30:45 -0400", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected_naive = NaiveDateTime::new(
NaiveDate::from_ymd_opt(2024, 4, 15).unwrap(),
NaiveTime::from_hms_opt(14, 30, 45).unwrap(),
);
let offset = FixedOffset::west_opt(4 * 3600).unwrap();
let expected = offset
.from_local_datetime(&expected_naive)
.single()
.unwrap();
assert_eq!(dt, expected);
assert_eq!(dt.offset(), &offset);
}
#[test]
fn test_to_chrono_datetime_colon_z_offset() {
let parsed = Parts::from_str(
"%F %T %:z",
"2024-04-15 14:30:45 -04:00",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected_naive = NaiveDateTime::new(
NaiveDate::from_ymd_opt(2024, 4, 15).unwrap(),
NaiveTime::from_hms_opt(14, 30, 45).unwrap(),
);
let offset = FixedOffset::west_opt(4 * 3600).unwrap();
let expected = offset
.from_local_datetime(&expected_naive)
.single()
.unwrap();
assert_eq!(dt, expected);
}
#[test]
fn test_to_chrono_datetime_unix_timestamp_direct() {
let parsed = Parts::from_str("%s", "1713191445", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected_utc = DateTime::from_timestamp(1713191445, 0).unwrap();
let offset = FixedOffset::east_opt(0).unwrap();
let expected = expected_utc.with_timezone(&offset);
assert_eq!(dt, expected);
assert_eq!(dt.timestamp(), 1713191445);
}
#[test]
fn test_to_chrono_datetime_unix_timestamp_with_fraction() {
let parsed = Parts::from_str("%s", "1713191445.123456789", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected_utc = DateTime::from_timestamp(1713191445, 123_456_789).unwrap();
let offset = FixedOffset::east_opt(0).unwrap();
let expected = expected_utc.with_timezone(&offset);
assert_eq!(dt, expected);
}
#[test]
fn test_to_chrono_timestamp_basic() {
let parsed = Parts::from_str(
"%Y-%m-%d %H:%M:%S",
"2024-04-15 14:30:45",
false,
false,
false,
)
.unwrap();
let ts = parsed.to_chrono_timestamp().unwrap();
assert_eq!(ts, 1713191445);
}
#[test]
fn test_to_chrono_timestamp_unix_direct() {
let parsed = Parts::from_str("%s", "1713191445", false, false, false).unwrap();
let ts = parsed.to_chrono_timestamp().unwrap();
assert_eq!(ts, 1713191445);
}
#[test]
fn test_to_chrono_timestamp_with_offset() {
let parsed =
Parts::from_str("%F %T %z", "2024-04-15 10:30:45 -0400", false, false, false).unwrap();
let ts = parsed.to_chrono_timestamp().unwrap();
assert_eq!(ts, 1713191445);
}
#[test]
fn test_to_chrono_naive_datetime_incomplete_date_fails_in_finish_but_assembly_fails_here() {
let parsed = Parts::from_str("%H:%M:%S", "14:30:45", false, false, false);
assert!(parsed.is_err()); }
#[test]
fn test_to_chrono_datetime_utc_explicit() {
let parsed =
Parts::from_str("%F %T %z", "2024-04-15 14:30:45 +0000", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected = DateTime::from_timestamp(1713191445, 0)
.unwrap()
.with_timezone(&FixedOffset::east_opt(0).unwrap());
assert_eq!(dt, expected);
}
#[test]
fn test_to_chrono_datetime_civil_with_fixed_positive_offset() {
let parsed =
Parts::from_str("%F %T %z", "2024-04-15 14:30:45 +0500", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
let expected_naive = NaiveDateTime::new(
NaiveDate::from_ymd_opt(2024, 4, 15).unwrap(),
NaiveTime::from_hms_opt(14, 30, 45).unwrap(),
);
let offset = FixedOffset::east_opt(5 * 3600).unwrap();
let expected = offset
.from_local_datetime(&expected_naive)
.single()
.unwrap();
assert_eq!(dt, expected);
assert_eq!(dt.offset(), &offset);
assert_eq!(dt.timestamp(), 1713173445); }
#[test]
fn test_to_chrono_datetime_civil_with_iana_america_new_york_edt() {
let parsed = Parts::from_str(
"%F %T %Q",
"2024-04-15 10:30:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap());
assert_eq!(dt.timestamp(), 1713191400); }
#[test]
fn test_to_chrono_datetime_civil_with_iana_fallback_offset_at() {
let parsed = Parts::from_str(
"%F %T %Q",
"2024-04-15 10:30:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap());
assert_eq!(dt.timestamp(), 1713191400);
}
#[test]
fn test_to_chrono_datetime_unix_timestamp_ignores_iana_name() {
let parsed =
Parts::from_str("%s %Q", "1713191400 America/New_York", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::east_opt(0).unwrap());
assert_eq!(dt.timestamp(), 1713191400);
}
#[test]
fn test_to_chrono_datetime_unix_timestamp_ignores_fixed_offset() {
let parsed = Parts::from_str("%s %z", "1713191400 -0400", false, false, false).unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::east_opt(0).unwrap());
assert_eq!(dt.timestamp(), 1713191400);
}
#[test]
fn test_to_chrono_timestamp_with_iana_name() {
let parsed = Parts::from_str(
"%F %T %Q",
"2024-04-15 10:30:00 America/New_York",
false,
false,
false,
)
.unwrap();
let ts = parsed.to_chrono_timestamp().unwrap();
assert_eq!(ts, 1713191400); }
#[test]
fn test_to_chrono_datetime_iana_spring_forward_gap() {
let parsed = Parts::from_str(
"%F %T %Q",
"2023-03-12 02:30:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap());
assert_eq!(dt.timestamp(), 1678606200); }
#[test]
fn test_to_chrono_datetime_iana_exact_spring_forward_boundary() {
let parsed = Parts::from_str(
"%F %T %Q",
"2023-03-12 02:00:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap());
assert_eq!(dt.timestamp(), 1678604400);
}
#[test]
fn test_to_chrono_datetime_iana_fall_back_overlap() {
let parsed = Parts::from_str(
"%F %T %Q",
"2023-11-05 01:00:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap()); assert_eq!(dt.timestamp(), 1699160400); }
#[test]
fn test_to_chrono_datetime_iana_exact_fall_back_boundary() {
let parsed = Parts::from_str(
"%F %T %Q",
"2023-11-05 01:00:00 America/New_York",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::west_opt(4 * 3600).unwrap()); assert_eq!(dt.timestamp(), 1699160400); }
#[test]
fn test_to_chrono_datetime_iana_southern_hemisphere_gap() {
let parsed = Parts::from_str(
"%F %T %Q",
"2024-10-06 02:30:00 Australia/Sydney",
false,
false,
false,
)
.unwrap();
let dt = parsed.to_chrono_datetime().unwrap();
assert_eq!(dt.offset(), &FixedOffset::east_opt(11 * 3600).unwrap()); assert_eq!(dt.timestamp(), 1728145800); }
}