From 20c629a26c628a4e9e9915546b0d3a701a4789c0 Mon Sep 17 00:00:00 2001 From: Robert Bastian Date: Wed, 30 Oct 2024 13:24:44 +0100 Subject: [PATCH] unix --- Cargo.lock | 1 + components/calendar/Cargo.toml | 4 - components/calendar/benches/iso.rs | 20 --- components/calendar/src/date.rs | 22 ++- components/calendar/src/iso.rs | 101 +----------- components/calendar/src/types.rs | 147 ------------------ components/datetime/benches/datetime.rs | 5 +- components/datetime/src/neo_pattern.rs | 5 +- .../datetime/src/provider/time_zones.rs | 2 +- components/datetime/src/time_zone.rs | 8 +- .../datetime/tests/resolved_components.rs | 7 +- components/timezone/Cargo.toml | 1 + components/timezone/src/ixdtf.rs | 43 +++-- components/timezone/src/provider.rs | 9 +- components/timezone/src/zone_offset.rs | 12 +- ffi/capi/bindings/c/IsoDate.h | 2 - ffi/capi/bindings/c/IsoDateTime.h | 6 - ffi/capi/bindings/cpp/icu4x/IsoDate.d.hpp | 2 - ffi/capi/bindings/cpp/icu4x/IsoDate.hpp | 7 - ffi/capi/bindings/cpp/icu4x/IsoDateTime.d.hpp | 6 - ffi/capi/bindings/cpp/icu4x/IsoDateTime.hpp | 21 --- ffi/capi/bindings/dart/IsoDate.g.dart | 13 -- ffi/capi/bindings/dart/IsoDateTime.g.dart | 39 ----- ffi/capi/bindings/js/IsoDate.d.ts | 2 - ffi/capi/bindings/js/IsoDate.mjs | 10 -- ffi/capi/bindings/js/IsoDateTime.d.ts | 6 - ffi/capi/bindings/js/IsoDateTime.mjs | 30 ---- ffi/capi/src/date.rs | 7 - ffi/capi/src/datetime.rs | 27 ---- provider/source/src/time_zones/convert.rs | 22 ++- 30 files changed, 88 insertions(+), 499 deletions(-) delete mode 100644 components/calendar/benches/iso.rs diff --git a/Cargo.lock b/Cargo.lock index dabbbe8a9b1..3db09e16dba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1696,6 +1696,7 @@ dependencies = [ name = "icu_timezone" version = "1.5.0" dependencies = [ + "calendrical_calculations", "databake", "displaydoc", "icu", diff --git a/components/calendar/Cargo.toml b/components/calendar/Cargo.toml index 43b818b4089..96db50a1770 100644 --- a/components/calendar/Cargo.toml +++ b/components/calendar/Cargo.toml @@ -68,10 +68,6 @@ harness = false name = "datetime" harness = false -[[bench]] -name = "iso" -harness = false - [[bench]] name = "convert" harness = false diff --git a/components/calendar/benches/iso.rs b/components/calendar/benches/iso.rs deleted file mode 100644 index 184ba0ce2f6..00000000000 --- a/components/calendar/benches/iso.rs +++ /dev/null @@ -1,20 +0,0 @@ -// This file is part of ICU4X. For terms of use, please see the file -// called LICENSE at the top level of the ICU4X source tree -// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). - -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use icu_calendar::{DateTime, Iso}; - -fn overview_bench(c: &mut Criterion) { - c.bench_function("iso/from_minutes_since_local_unix_epoch", |b| { - b.iter(|| { - for i in -250..250 { - let minutes = i * 10000; - DateTime::::from_minutes_since_local_unix_epoch(black_box(minutes)); - } - }); - }); -} - -criterion_group!(benches, overview_bench,); -criterion_main!(benches); diff --git a/components/calendar/src/date.rs b/components/calendar/src/date.rs index aeb15ba2e55..21b047b2821 100644 --- a/components/calendar/src/date.rs +++ b/components/calendar/src/date.rs @@ -320,12 +320,30 @@ impl Date { &self.calendar } - #[cfg(test)] - pub(crate) fn to_fixed(&self) -> calendrical_calculations::rata_die::RataDie { + #[doc(hidden)] + pub fn to_fixed(&self) -> calendrical_calculations::rata_die::RataDie { Iso::fixed_from_iso(self.to_iso().inner) } } +impl Date { + /// Calculates the number of days between two dates. + /// + /// ```rust + /// use icu::calendar::Date; + /// use icu::calendar::DateDurationUnit; + /// + /// let a = Date::try_new_iso(1994, 12, 10).unwrap(); + /// let b = Date::try_new_iso(2024, 10, 30).unwrap(); + /// + /// assert_eq!(b.days_since(a), 10_917); + /// ``` + #[doc(hidden)] // unstable + pub fn days_since(&self, other: Date) -> i32 { + (Iso::fixed_from_iso(*self.inner()) - Iso::fixed_from_iso(other.inner)) as i32 + } +} + impl> Date { /// Type-erase the date, converting it to a date for [`AnyCalendar`] pub fn to_any(&self) -> Date { diff --git a/components/calendar/src/iso.rs b/components/calendar/src/iso.rs index e975659df2c..cd823611f39 100644 --- a/components/calendar/src/iso.rs +++ b/components/calendar/src/iso.rs @@ -32,7 +32,7 @@ use crate::calendar_arithmetic::{ArithmeticDate, CalendarArithmetic}; use crate::error::DateError; use crate::{types, Calendar, Date, DateDuration, DateDurationUnit, DateTime, RangeError, Time}; -use calendrical_calculations::helpers::{i64_to_saturated_i32, I32CastError}; +use calendrical_calculations::helpers::I32CastError; use calendrical_calculations::rata_die::RataDie; use tinystr::tinystr; @@ -252,11 +252,6 @@ impl Date { .map(IsoDateInner) .map(|inner| Date::from_raw(inner, Iso)) } - - /// Constructs an ISO date representing the UNIX epoch on January 1, 1970. - pub fn unix_epoch() -> Self { - Date::from_raw(IsoDateInner(ArithmeticDate::new_unchecked(1970, 1, 1)), Iso) - } } impl DateTime { @@ -288,83 +283,6 @@ impl DateTime { time: Time::try_new(hour, minute, second, 0)?, }) } - - /// Constructs an ISO datetime representing the UNIX epoch on January 1, 1970 - /// at midnight. - pub fn local_unix_epoch() -> Self { - DateTime { - date: Date::unix_epoch(), - time: Time::midnight(), - } - } - - /// Minute count representation of calendars starting from 00:00:00 on Jan 1st, 1970. - /// - /// ```rust - /// use icu::calendar::DateTime; - /// - /// let today = DateTime::try_new_iso(2020, 2, 29, 0, 0, 0).unwrap(); - /// - /// assert_eq!(today.minutes_since_local_unix_epoch(), 26382240); - /// assert_eq!( - /// DateTime::from_minutes_since_local_unix_epoch(26382240), - /// today - /// ); - /// - /// let today = DateTime::try_new_iso(1970, 1, 1, 0, 0, 0).unwrap(); - /// - /// assert_eq!(today.minutes_since_local_unix_epoch(), 0); - /// assert_eq!(DateTime::from_minutes_since_local_unix_epoch(0), today); - /// ``` - pub fn minutes_since_local_unix_epoch(&self) -> i32 { - let minutes_a_hour = 60; - let hours_a_day = 24; - let minutes_a_day = minutes_a_hour * hours_a_day; - let unix_epoch = Iso::fixed_from_iso(Date::unix_epoch().inner); - let result = (Iso::fixed_from_iso(*self.date.inner()) - unix_epoch) * minutes_a_day - + i64::from(self.time.hour.number()) * minutes_a_hour - + i64::from(self.time.minute.number()); - i64_to_saturated_i32(result) - } - - /// Convert minute count since 00:00:00 on Jan 1st, 1970 to ISO Date. - /// - /// # Examples - /// - /// ```rust - /// use icu::calendar::DateTime; - /// - /// // After Unix Epoch - /// let today = DateTime::try_new_iso(2020, 2, 29, 0, 0, 0).unwrap(); - /// - /// assert_eq!(today.minutes_since_local_unix_epoch(), 26382240); - /// assert_eq!( - /// DateTime::from_minutes_since_local_unix_epoch(26382240), - /// today - /// ); - /// - /// // Unix Epoch - /// let today = DateTime::try_new_iso(1970, 1, 1, 0, 0, 0).unwrap(); - /// - /// assert_eq!(today.minutes_since_local_unix_epoch(), 0); - /// assert_eq!(DateTime::from_minutes_since_local_unix_epoch(0), today); - /// - /// // Before Unix Epoch - /// let today = DateTime::try_new_iso(1967, 4, 6, 20, 40, 0).unwrap(); - /// - /// assert_eq!(today.minutes_since_local_unix_epoch(), -1440200); - /// assert_eq!( - /// DateTime::from_minutes_since_local_unix_epoch(-1440200), - /// today - /// ); - /// ``` - pub fn from_minutes_since_local_unix_epoch(minute: i32) -> DateTime { - let (time, extra_days) = Time::from_minute_with_remainder_days(minute); - let unix_epoch = Date::unix_epoch(); - let unix_epoch_days = Iso::fixed_from_iso(unix_epoch.inner); - let date = Iso::iso_from_fixed(unix_epoch_days + extra_days as i64); - DateTime { date, time } - } } impl Iso { @@ -823,21 +741,4 @@ mod test { check(1461, 4, 12, 31); // leap year check(1462, 5, 1, 1); } - - #[test] - fn test_from_minutes_since_local_unix_epoch() { - fn check(minutes: i32, year: i32, month: u8, day: u8, hour: u8, minute: u8) { - let today = DateTime::try_new_iso(year, month, day, hour, minute, 0).unwrap(); - assert_eq!(today.minutes_since_local_unix_epoch(), minutes); - assert_eq!( - DateTime::from_minutes_since_local_unix_epoch(minutes), - today - ); - } - - check(-1441, 1969, 12, 30, 23, 59); - check(-1440, 1969, 12, 31, 0, 0); - check(-1439, 1969, 12, 31, 0, 1); - check(-2879, 1969, 12, 30, 0, 1); - } } diff --git a/components/calendar/src/types.rs b/components/calendar/src/types.rs index a23c46e6b46..50555900346 100644 --- a/components/calendar/src/types.rs +++ b/components/calendar/src/types.rs @@ -679,153 +679,6 @@ impl Time { nanosecond: nanosecond.try_into()?, }) } - - /// Takes a number of minutes, which could be positive or negative, and returns the Time - /// and the day number, which could be positive or negative. - pub(crate) fn from_minute_with_remainder_days(minute: i32) -> (Time, i32) { - let (extra_days, minute_in_day) = (minute.div_euclid(1440), minute.rem_euclid(1440)); - let (hours, minutes) = (minute_in_day / 60, minute_in_day % 60); - #[allow(clippy::unwrap_used)] // values are moduloed to be in range - ( - Self { - hour: (hours as u8).try_into().unwrap(), - minute: (minutes as u8).try_into().unwrap(), - second: IsoSecond::zero(), - nanosecond: NanoSecond::zero(), - }, - extra_days, - ) - } -} - -#[test] -fn test_from_minute_with_remainder_days() { - #[derive(Debug)] - struct TestCase { - minute: i32, - expected_time: Time, - expected_remainder: i32, - } - let zero_time = Time::new( - IsoHour::zero(), - IsoMinute::zero(), - IsoSecond::zero(), - NanoSecond::zero(), - ); - let first_minute_in_day = Time::new( - IsoHour::zero(), - IsoMinute::try_from(1u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ); - let last_minute_in_day = Time::new( - IsoHour::try_from(23u8).unwrap(), - IsoMinute::try_from(59u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ); - let cases = [ - TestCase { - minute: 0, - expected_time: zero_time, - expected_remainder: 0, - }, - TestCase { - minute: 30, - expected_time: Time::new( - IsoHour::zero(), - IsoMinute::try_from(30u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: 0, - }, - TestCase { - minute: 60, - expected_time: Time::new( - IsoHour::try_from(1u8).unwrap(), - IsoMinute::zero(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: 0, - }, - TestCase { - minute: 90, - expected_time: Time::new( - IsoHour::try_from(1u8).unwrap(), - IsoMinute::try_from(30u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: 0, - }, - TestCase { - minute: 1439, - expected_time: last_minute_in_day, - expected_remainder: 0, - }, - TestCase { - minute: 1440, - expected_time: Time::new( - IsoHour::zero(), - IsoMinute::zero(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: 1, - }, - TestCase { - minute: 1441, - expected_time: first_minute_in_day, - expected_remainder: 1, - }, - TestCase { - minute: i32::MAX, - expected_time: Time::new( - IsoHour::try_from(2u8).unwrap(), - IsoMinute::try_from(7u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: 1491308, - }, - TestCase { - minute: -1, - expected_time: last_minute_in_day, - expected_remainder: -1, - }, - TestCase { - minute: -1439, - expected_time: first_minute_in_day, - expected_remainder: -1, - }, - TestCase { - minute: -1440, - expected_time: zero_time, - expected_remainder: -1, - }, - TestCase { - minute: -1441, - expected_time: last_minute_in_day, - expected_remainder: -2, - }, - TestCase { - minute: i32::MIN, - expected_time: Time::new( - IsoHour::try_from(21u8).unwrap(), - IsoMinute::try_from(52u8).unwrap(), - IsoSecond::zero(), - NanoSecond::zero(), - ), - expected_remainder: -1491309, - }, - ]; - for cas in cases { - let (actual_time, actual_remainder) = Time::from_minute_with_remainder_days(cas.minute); - assert_eq!(actual_time, cas.expected_time, "{cas:?}"); - assert_eq!(actual_remainder, cas.expected_remainder, "{cas:?}"); - } } /// A weekday in a 7-day week, according to ISO-8601. diff --git a/components/datetime/benches/datetime.rs b/components/datetime/benches/datetime.rs index f253847da02..da33e2631f5 100644 --- a/components/datetime/benches/datetime.rs +++ b/components/datetime/benches/datetime.rs @@ -36,7 +36,10 @@ fn datetime_benches(c: &mut Criterion) { time, // zone is unused but we need to make the types match zone: TimeZoneInfo::utc() - .at_time((Date::unix_epoch(), Time::midnight())) + .at_time(( + Date::try_new_iso(2024, 1, 1).unwrap(), + Time::midnight(), + )) .with_zone_variant(ZoneVariant::standard()), } } diff --git a/components/datetime/src/neo_pattern.rs b/components/datetime/src/neo_pattern.rs index c25a3454a41..e423f4a469b 100644 --- a/components/datetime/src/neo_pattern.rs +++ b/components/datetime/src/neo_pattern.rs @@ -37,7 +37,7 @@ size_test!(DateTimePattern, date_time_pattern_size, 32); /// then check the resolved components: /// /// ``` -/// use icu::calendar::DateTime; +/// use icu::calendar::Date; /// use icu::calendar::Gregorian; /// use icu::datetime::fieldset::YMD; /// use icu::datetime::neo_pattern::DateTimePattern; @@ -59,8 +59,7 @@ size_test!(DateTimePattern, date_time_pattern_size, 32); /// ) /// .unwrap() /// // The pattern can depend on the datetime being formatted. -/// // For this example, we'll choose the local Unix epoch. -/// .format(&DateTime::local_unix_epoch().to_calendar(Gregorian)) +/// .format(&Date::try_new_iso(2024, 1, 1).unwrap().to_calendar(Gregorian)) /// .pattern(); /// assert_writeable_eq!(data_pattern, pattern_str); /// assert_eq!(custom_pattern, data_pattern); diff --git a/components/datetime/src/provider/time_zones.rs b/components/datetime/src/provider/time_zones.rs index 345a3bb1f1c..0764021e3bb 100644 --- a/components/datetime/src/provider/time_zones.rs +++ b/components/datetime/src/provider/time_zones.rs @@ -231,7 +231,7 @@ impl<'a> zerovec::maps::ZeroMapKV<'a> for MetazoneId { #[yoke(prove_covariance_manually)] pub struct MetazonePeriodV1<'data>( /// The default mapping between period and metazone id. The second level key is a wall-clock time represented as - /// the number of minutes since the local unix epoch. It represents when the metazone started to be used. + /// the number of minutes since the local [`EPOCH`](icu_timezone::provider::EPOCH). It represents when the metazone started to be used. #[cfg_attr(feature = "serde", serde(borrow))] pub ZeroMap2d<'data, TimeZoneBcp47Id, IsoMinutesSinceEpoch, Option>, ); diff --git a/components/datetime/src/time_zone.rs b/components/datetime/src/time_zone.rs index 0f6c5a44a8d..6498cef23e2 100644 --- a/components/datetime/src/time_zone.rs +++ b/components/datetime/src/time_zone.rs @@ -14,6 +14,7 @@ use core::fmt; use fixed_decimal::FixedDecimal; use icu_calendar::{Date, Iso, Time}; use icu_decimal::FixedDecimalFormatter; +use icu_timezone::provider::EPOCH; use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; use writeable::Writeable; @@ -230,11 +231,10 @@ fn metazone( ) -> Option { let cursor = metazone_period.0.get0(&time_zone_id)?; let mut metazone_id = None; - let minutes_since_local_unix_epoch = - icu_calendar::DateTime { date, time }.minutes_since_local_unix_epoch(); + let minutes_since_epoch_walltime = (date.to_fixed() - EPOCH) as i32 * 24 * 60 + + (time.hour.number() as i32 * 60 + time.minute.number() as i32); for (minutes, id) in cursor.iter1() { - if minutes_since_local_unix_epoch >= ::from_unaligned(*minutes) - { + if minutes_since_epoch_walltime >= ::from_unaligned(*minutes) { metazone_id = id.get() } else { break; diff --git a/components/datetime/tests/resolved_components.rs b/components/datetime/tests/resolved_components.rs index ac3ebd515b7..539423e53e0 100644 --- a/components/datetime/tests/resolved_components.rs +++ b/components/datetime/tests/resolved_components.rs @@ -2,7 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use icu_calendar::{DateTime, Gregorian}; +use icu_calendar::{Date, DateTime, Gregorian, Time}; use icu_datetime::{ neo_skeleton::{ Alignment, FractionalSecondDigits, NeoDateComponents, NeoDateTimeComponents, @@ -24,7 +24,10 @@ fn assert_resolved_components( skeleton, ) .unwrap(); - let datetime = DateTime::local_unix_epoch().to_calendar(Gregorian); + let datetime = DateTime { + date: Date::try_new_gregorian(2024, 1, 1).unwrap(), + time: Time::midnight(), + }; let resolved_pattern = dtf.format(&datetime).pattern(); assert_eq!(components::Bag::from(&resolved_pattern), *bag); } diff --git a/components/timezone/Cargo.toml b/components/timezone/Cargo.toml index 62d04295d81..91a4c20ebff 100644 --- a/components/timezone/Cargo.toml +++ b/components/timezone/Cargo.toml @@ -20,6 +20,7 @@ version.workspace = true all-features = true [dependencies] +calendrical_calculations = { workspace = true } displaydoc = { workspace = true } icu_calendar = { workspace = true } icu_provider = { workspace = true, features = ["macros"] } diff --git a/components/timezone/src/ixdtf.rs b/components/timezone/src/ixdtf.rs index 5bd6e6e4b58..303076ad865 100644 --- a/components/timezone/src/ixdtf.rs +++ b/components/timezone/src/ixdtf.rs @@ -301,35 +301,30 @@ impl<'a> Intermediate<'a> { return Err(ParseError::MismatchedTimeZoneFields); }; let time_zone_id = mapper.iana_bytes_to_bcp47(iana_identifier); - let iso = DateTime::::try_new_iso( - self.date.year, - self.date.month, - self.date.day, - self.time.hour, - self.time.minute, - self.time.second, - )?; + let date = Date::try_new_iso(self.date.year, self.date.month, self.date.day)?; + let time = Time::try_new(self.time.hour, self.time.minute, self.time.second, 0)?; let offset = UtcOffset::try_from_utc_offset_record(offset)?; - let zone_variant = - match zone_offset_calculator.compute_offsets_from_time_zone(time_zone_id, &iso) { - Some((std_offset, dst_offset)) => { - if offset == std_offset { - ZoneVariant::standard() - } else if Some(offset) == dst_offset { - ZoneVariant::daylight() - } else { - return Err(ParseError::InvalidOffsetError); - } - } - None => { - // time_zone_id not found; Etc/Unknown? - debug_assert_eq!(time_zone_id.0.as_str(), "unk"); + let zone_variant = match zone_offset_calculator + .compute_offsets_from_time_zone(time_zone_id, (date, time)) + { + Some((std_offset, dst_offset)) => { + if offset == std_offset { ZoneVariant::standard() + } else if Some(offset) == dst_offset { + ZoneVariant::daylight() + } else { + return Err(ParseError::InvalidOffsetError); } - }; + } + None => { + // time_zone_id not found; Etc/Unknown? + debug_assert_eq!(time_zone_id.0.as_str(), "unk"); + ZoneVariant::standard() + } + }; Ok(offset .with_id(time_zone_id) - .at_time((iso.date, iso.time)) + .at_time((date, time)) .with_zone_variant(zone_variant)) } } diff --git a/components/timezone/src/provider.rs b/components/timezone/src/provider.rs index fbe55399704..5e01aede48a 100644 --- a/components/timezone/src/provider.rs +++ b/components/timezone/src/provider.rs @@ -15,6 +15,7 @@ //! //! Read more about data providers: [`icu_provider`] +use calendrical_calculations::rata_die::RataDie; use core::ops::Deref; use icu_provider::prelude::*; use tinystr::TinyAsciiStr; @@ -113,8 +114,12 @@ impl<'a> zerovec::maps::ZeroMapKV<'a> for TimeZoneBcp47Id { /// Storage type for storing UTC offsets as eights of an hour. pub type EighthsOfHourOffset = i8; -/// Storage type for storing `DateTime` as minutes since the UNIX epoch. +/// Storage type for storing `DateTime` as minutes since [`EPOCH`]. pub type IsoMinutesSinceEpoch = i32; +/// The epoch for [`IsoMinutesSinceEpoch`]. +/// +/// This is 1970-01-01, but this is coincidental to anything UNIX and should be changed to 0 in the future. +pub const EPOCH: RataDie = RataDie::new(719163); /// An ICU4X mapping to the time zone offsets at a given period. /// @@ -135,7 +140,7 @@ pub type IsoMinutesSinceEpoch = i32; #[yoke(prove_covariance_manually)] pub struct ZoneOffsetPeriodV1<'data>( /// The default mapping between period and offsets. The second level key is a wall-clock time represented as - /// the number of minutes since the local unix epoch. It represents when the offsets ended to be used. + /// the number of minutes since the local [`EPOCH`]. It represents when the offsets ended to be used. /// /// The values are the standard offset, and the daylight offset *relative to the standard offset*. As such, /// if the second value is 0, there is no daylight time. diff --git a/components/timezone/src/zone_offset.rs b/components/timezone/src/zone_offset.rs index 8fcb7f4fdba..ad0247bd645 100644 --- a/components/timezone/src/zone_offset.rs +++ b/components/timezone/src/zone_offset.rs @@ -2,10 +2,10 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use crate::provider::ZoneOffsetPeriodV1Marker; +use crate::provider::{ZoneOffsetPeriodV1Marker, EPOCH}; use crate::{TimeZoneBcp47Id, UtcOffset}; -use icu_calendar::DateTime; use icu_calendar::Iso; +use icu_calendar::{Date, Time}; use icu_provider::prelude::*; /// [`ZoneOffsetCalculator`] uses data from the [data provider] to calculate time zone offsets. @@ -93,16 +93,16 @@ impl ZoneOffsetCalculator { pub fn compute_offsets_from_time_zone( &self, time_zone_id: TimeZoneBcp47Id, - local_datetime: &DateTime, + (date, time): (Date, Time), ) -> Option<(UtcOffset, Option)> { use zerovec::ule::AsULE; match self.offset_period.get().0.get0(&time_zone_id) { Some(cursor) => { let mut offsets = None; - let minutes_since_local_unix_epoch = - local_datetime.minutes_since_local_unix_epoch(); + let minutes_since_epoch_walltime = (date.to_fixed() - EPOCH) as i32 * 24 * 60 + + (time.hour.number() as i32 * 60 + time.minute.number() as i32); for (minutes, id) in cursor.iter1_copied().rev() { - if minutes_since_local_unix_epoch <= i32::from_unaligned(*minutes) { + if minutes_since_epoch_walltime <= i32::from_unaligned(*minutes) { offsets = Some(id); } else { break; diff --git a/ffi/capi/bindings/c/IsoDate.h b/ffi/capi/bindings/c/IsoDate.h index ae7aefcdd5e..c276af32ca1 100644 --- a/ffi/capi/bindings/c/IsoDate.h +++ b/ffi/capi/bindings/c/IsoDate.h @@ -28,8 +28,6 @@ icu4x_IsoDate_create_mv1_result icu4x_IsoDate_create_mv1(int32_t year, uint8_t m typedef struct icu4x_IsoDate_from_string_mv1_result {union {IsoDate* ok; CalendarParseError err;}; bool is_ok;} icu4x_IsoDate_from_string_mv1_result; icu4x_IsoDate_from_string_mv1_result icu4x_IsoDate_from_string_mv1(DiplomatStringView v); -IsoDate* icu4x_IsoDate_unix_epoch_mv1(void); - Date* icu4x_IsoDate_to_calendar_mv1(const IsoDate* self, const Calendar* calendar); Date* icu4x_IsoDate_to_any_mv1(const IsoDate* self); diff --git a/ffi/capi/bindings/c/IsoDateTime.h b/ffi/capi/bindings/c/IsoDateTime.h index c47bbe08b2e..2c3986a5f0a 100644 --- a/ffi/capi/bindings/c/IsoDateTime.h +++ b/ffi/capi/bindings/c/IsoDateTime.h @@ -32,18 +32,12 @@ IsoDateTime* icu4x_IsoDateTime_from_date_and_time_mv1(const IsoDate* date, const typedef struct icu4x_IsoDateTime_from_string_mv1_result {union {IsoDateTime* ok; CalendarParseError err;}; bool is_ok;} icu4x_IsoDateTime_from_string_mv1_result; icu4x_IsoDateTime_from_string_mv1_result icu4x_IsoDateTime_from_string_mv1(DiplomatStringView v); -IsoDateTime* icu4x_IsoDateTime_local_unix_epoch_mv1(void); - -IsoDateTime* icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(int32_t minutes); - IsoDate* icu4x_IsoDateTime_date_mv1(const IsoDateTime* self); Time* icu4x_IsoDateTime_time_mv1(const IsoDateTime* self); DateTime* icu4x_IsoDateTime_to_any_mv1(const IsoDateTime* self); -int32_t icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(const IsoDateTime* self); - DateTime* icu4x_IsoDateTime_to_calendar_mv1(const IsoDateTime* self, const Calendar* calendar); uint8_t icu4x_IsoDateTime_hour_mv1(const IsoDateTime* self); diff --git a/ffi/capi/bindings/cpp/icu4x/IsoDate.d.hpp b/ffi/capi/bindings/cpp/icu4x/IsoDate.d.hpp index fb48e8a6def..9f4c8b955f1 100644 --- a/ffi/capi/bindings/cpp/icu4x/IsoDate.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/IsoDate.d.hpp @@ -39,8 +39,6 @@ class IsoDate { inline static diplomat::result, icu4x::CalendarParseError> from_string(std::string_view v); - inline static std::unique_ptr unix_epoch(); - inline std::unique_ptr to_calendar(const icu4x::Calendar& calendar) const; inline std::unique_ptr to_any() const; diff --git a/ffi/capi/bindings/cpp/icu4x/IsoDate.hpp b/ffi/capi/bindings/cpp/icu4x/IsoDate.hpp index 9810abcf604..4251a003ab1 100644 --- a/ffi/capi/bindings/cpp/icu4x/IsoDate.hpp +++ b/ffi/capi/bindings/cpp/icu4x/IsoDate.hpp @@ -29,8 +29,6 @@ namespace capi { typedef struct icu4x_IsoDate_from_string_mv1_result {union {icu4x::capi::IsoDate* ok; icu4x::capi::CalendarParseError err;}; bool is_ok;} icu4x_IsoDate_from_string_mv1_result; icu4x_IsoDate_from_string_mv1_result icu4x_IsoDate_from_string_mv1(diplomat::capi::DiplomatStringView v); - icu4x::capi::IsoDate* icu4x_IsoDate_unix_epoch_mv1(void); - icu4x::capi::Date* icu4x_IsoDate_to_calendar_mv1(const icu4x::capi::IsoDate* self, const icu4x::capi::Calendar* calendar); icu4x::capi::Date* icu4x_IsoDate_to_any_mv1(const icu4x::capi::IsoDate* self); @@ -76,11 +74,6 @@ inline diplomat::result, icu4x::CalendarParseErr return result.is_ok ? diplomat::result, icu4x::CalendarParseError>(diplomat::Ok>(std::unique_ptr(icu4x::IsoDate::FromFFI(result.ok)))) : diplomat::result, icu4x::CalendarParseError>(diplomat::Err(icu4x::CalendarParseError::FromFFI(result.err))); } -inline std::unique_ptr icu4x::IsoDate::unix_epoch() { - auto result = icu4x::capi::icu4x_IsoDate_unix_epoch_mv1(); - return std::unique_ptr(icu4x::IsoDate::FromFFI(result)); -} - inline std::unique_ptr icu4x::IsoDate::to_calendar(const icu4x::Calendar& calendar) const { auto result = icu4x::capi::icu4x_IsoDate_to_calendar_mv1(this->AsFFI(), calendar.AsFFI()); diff --git a/ffi/capi/bindings/cpp/icu4x/IsoDateTime.d.hpp b/ffi/capi/bindings/cpp/icu4x/IsoDateTime.d.hpp index 31587901945..68dd384509d 100644 --- a/ffi/capi/bindings/cpp/icu4x/IsoDateTime.d.hpp +++ b/ffi/capi/bindings/cpp/icu4x/IsoDateTime.d.hpp @@ -45,18 +45,12 @@ class IsoDateTime { inline static diplomat::result, icu4x::CalendarParseError> from_string(std::string_view v); - inline static std::unique_ptr local_unix_epoch(); - - inline static std::unique_ptr from_minutes_since_local_unix_epoch(int32_t minutes); - inline std::unique_ptr date() const; inline std::unique_ptr time() const; inline std::unique_ptr to_any() const; - inline int32_t minutes_since_local_unix_epoch() const; - inline std::unique_ptr to_calendar(const icu4x::Calendar& calendar) const; inline uint8_t hour() const; diff --git a/ffi/capi/bindings/cpp/icu4x/IsoDateTime.hpp b/ffi/capi/bindings/cpp/icu4x/IsoDateTime.hpp index 59da0d02dd3..0b58c4bfb89 100644 --- a/ffi/capi/bindings/cpp/icu4x/IsoDateTime.hpp +++ b/ffi/capi/bindings/cpp/icu4x/IsoDateTime.hpp @@ -33,18 +33,12 @@ namespace capi { typedef struct icu4x_IsoDateTime_from_string_mv1_result {union {icu4x::capi::IsoDateTime* ok; icu4x::capi::CalendarParseError err;}; bool is_ok;} icu4x_IsoDateTime_from_string_mv1_result; icu4x_IsoDateTime_from_string_mv1_result icu4x_IsoDateTime_from_string_mv1(diplomat::capi::DiplomatStringView v); - icu4x::capi::IsoDateTime* icu4x_IsoDateTime_local_unix_epoch_mv1(void); - - icu4x::capi::IsoDateTime* icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(int32_t minutes); - icu4x::capi::IsoDate* icu4x_IsoDateTime_date_mv1(const icu4x::capi::IsoDateTime* self); icu4x::capi::Time* icu4x_IsoDateTime_time_mv1(const icu4x::capi::IsoDateTime* self); icu4x::capi::DateTime* icu4x_IsoDateTime_to_any_mv1(const icu4x::capi::IsoDateTime* self); - int32_t icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(const icu4x::capi::IsoDateTime* self); - icu4x::capi::DateTime* icu4x_IsoDateTime_to_calendar_mv1(const icu4x::capi::IsoDateTime* self, const icu4x::capi::Calendar* calendar); uint8_t icu4x_IsoDateTime_hour_mv1(const icu4x::capi::IsoDateTime* self); @@ -106,16 +100,6 @@ inline diplomat::result, icu4x::CalendarPars return result.is_ok ? diplomat::result, icu4x::CalendarParseError>(diplomat::Ok>(std::unique_ptr(icu4x::IsoDateTime::FromFFI(result.ok)))) : diplomat::result, icu4x::CalendarParseError>(diplomat::Err(icu4x::CalendarParseError::FromFFI(result.err))); } -inline std::unique_ptr icu4x::IsoDateTime::local_unix_epoch() { - auto result = icu4x::capi::icu4x_IsoDateTime_local_unix_epoch_mv1(); - return std::unique_ptr(icu4x::IsoDateTime::FromFFI(result)); -} - -inline std::unique_ptr icu4x::IsoDateTime::from_minutes_since_local_unix_epoch(int32_t minutes) { - auto result = icu4x::capi::icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(minutes); - return std::unique_ptr(icu4x::IsoDateTime::FromFFI(result)); -} - inline std::unique_ptr icu4x::IsoDateTime::date() const { auto result = icu4x::capi::icu4x_IsoDateTime_date_mv1(this->AsFFI()); return std::unique_ptr(icu4x::IsoDate::FromFFI(result)); @@ -131,11 +115,6 @@ inline std::unique_ptr icu4x::IsoDateTime::to_any() const { return std::unique_ptr(icu4x::DateTime::FromFFI(result)); } -inline int32_t icu4x::IsoDateTime::minutes_since_local_unix_epoch() const { - auto result = icu4x::capi::icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(this->AsFFI()); - return result; -} - inline std::unique_ptr icu4x::IsoDateTime::to_calendar(const icu4x::Calendar& calendar) const { auto result = icu4x::capi::icu4x_IsoDateTime_to_calendar_mv1(this->AsFFI(), calendar.AsFFI()); diff --git a/ffi/capi/bindings/dart/IsoDate.g.dart b/ffi/capi/bindings/dart/IsoDate.g.dart index ce6ebf802e1..09109a60196 100644 --- a/ffi/capi/bindings/dart/IsoDate.g.dart +++ b/ffi/capi/bindings/dart/IsoDate.g.dart @@ -51,14 +51,6 @@ final class IsoDate implements ffi.Finalizable { return IsoDate._fromFfi(result.union.ok, []); } - /// Creates a new [`IsoDate`] representing January 1, 1970. - /// - /// See the [Rust documentation for `unix_epoch`](https://docs.rs/icu/latest/icu/calendar/struct.Date.html#method.unix_epoch) for more information. - factory IsoDate.unixEpoch() { - final result = _icu4x_IsoDate_unix_epoch_mv1(); - return IsoDate._fromFfi(result, []); - } - /// Convert this date to one in a different calendar /// /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/calendar/struct.Date.html#method.to_calendar) for more information. @@ -184,11 +176,6 @@ external _ResultOpaqueInt32 _icu4x_IsoDate_create_mv1(int year, int month, int d // ignore: non_constant_identifier_names external _ResultOpaqueInt32 _icu4x_IsoDate_from_string_mv1(_SliceUtf8 v); -@meta.RecordUse() -@ffi.Native Function()>(isLeaf: true, symbol: 'icu4x_IsoDate_unix_epoch_mv1') -// ignore: non_constant_identifier_names -external ffi.Pointer _icu4x_IsoDate_unix_epoch_mv1(); - @meta.RecordUse() @ffi.Native Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_IsoDate_to_calendar_mv1') // ignore: non_constant_identifier_names diff --git a/ffi/capi/bindings/dart/IsoDateTime.g.dart b/ffi/capi/bindings/dart/IsoDateTime.g.dart index 837b68bf8ad..f7470207cf8 100644 --- a/ffi/capi/bindings/dart/IsoDateTime.g.dart +++ b/ffi/capi/bindings/dart/IsoDateTime.g.dart @@ -59,22 +59,6 @@ final class IsoDateTime implements ffi.Finalizable { return IsoDateTime._fromFfi(result.union.ok, []); } - /// Creates a new [`IsoDateTime`] of midnight on January 1, 1970 - /// - /// See the [Rust documentation for `local_unix_epoch`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.local_unix_epoch) for more information. - factory IsoDateTime.localUnixEpoch() { - final result = _icu4x_IsoDateTime_local_unix_epoch_mv1(); - return IsoDateTime._fromFfi(result, []); - } - - /// Construct from the minutes since the local unix epoch for this date (Jan 1 1970, 00:00) - /// - /// See the [Rust documentation for `from_minutes_since_local_unix_epoch`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.from_minutes_since_local_unix_epoch) for more information. - factory IsoDateTime.fromMinutesSinceLocalUnixEpoch(int minutes) { - final result = _icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(minutes); - return IsoDateTime._fromFfi(result, []); - } - /// Gets the date contained in this object /// /// See the [Rust documentation for `date`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#structfield.date) for more information. @@ -100,14 +84,6 @@ final class IsoDateTime implements ffi.Finalizable { return DateTime._fromFfi(result, []); } - /// Gets the minutes since the local unix epoch for this date (Jan 1 1970, 00:00) - /// - /// See the [Rust documentation for `minutes_since_local_unix_epoch`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.minutes_since_local_unix_epoch) for more information. - int get minutesSinceLocalUnixEpoch { - final result = _icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(_ffi); - return result; - } - /// Convert this datetime to one in a different calendar /// /// See the [Rust documentation for `to_calendar`](https://docs.rs/icu/latest/icu/calendar/struct.DateTime.html#method.to_calendar) for more information. @@ -262,16 +238,6 @@ external ffi.Pointer _icu4x_IsoDateTime_from_date_and_time_mv1(ffi.P // ignore: non_constant_identifier_names external _ResultOpaqueInt32 _icu4x_IsoDateTime_from_string_mv1(_SliceUtf8 v); -@meta.RecordUse() -@ffi.Native Function()>(isLeaf: true, symbol: 'icu4x_IsoDateTime_local_unix_epoch_mv1') -// ignore: non_constant_identifier_names -external ffi.Pointer _icu4x_IsoDateTime_local_unix_epoch_mv1(); - -@meta.RecordUse() -@ffi.Native Function(ffi.Int32)>(isLeaf: true, symbol: 'icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1') -// ignore: non_constant_identifier_names -external ffi.Pointer _icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(int minutes); - @meta.RecordUse() @ffi.Native Function(ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_IsoDateTime_date_mv1') // ignore: non_constant_identifier_names @@ -287,11 +253,6 @@ external ffi.Pointer _icu4x_IsoDateTime_time_mv1(ffi.Pointer _icu4x_IsoDateTime_to_any_mv1(ffi.Pointer self); -@meta.RecordUse() -@ffi.Native)>(isLeaf: true, symbol: 'icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1') -// ignore: non_constant_identifier_names -external int _icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(ffi.Pointer self); - @meta.RecordUse() @ffi.Native Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true, symbol: 'icu4x_IsoDateTime_to_calendar_mv1') // ignore: non_constant_identifier_names diff --git a/ffi/capi/bindings/js/IsoDate.d.ts b/ffi/capi/bindings/js/IsoDate.d.ts index 9ac1bf63ae3..cf5ad459f02 100644 --- a/ffi/capi/bindings/js/IsoDate.d.ts +++ b/ffi/capi/bindings/js/IsoDate.d.ts @@ -22,8 +22,6 @@ export class IsoDate { static fromString(v: string): IsoDate; - static unixEpoch(): IsoDate; - toCalendar(calendar: Calendar): Date; toAny(): Date; diff --git a/ffi/capi/bindings/js/IsoDate.mjs b/ffi/capi/bindings/js/IsoDate.mjs index 0a9976aa891..abc69bfecac 100644 --- a/ffi/capi/bindings/js/IsoDate.mjs +++ b/ffi/capi/bindings/js/IsoDate.mjs @@ -87,16 +87,6 @@ export class IsoDate { } } - static unixEpoch() { - const result = wasm.icu4x_IsoDate_unix_epoch_mv1(); - - try { - return new IsoDate(diplomatRuntime.internalConstructor, result, []); - } - - finally {} - } - toCalendar(calendar) { const result = wasm.icu4x_IsoDate_to_calendar_mv1(this.ffiValue, calendar.ffiValue); diff --git a/ffi/capi/bindings/js/IsoDateTime.d.ts b/ffi/capi/bindings/js/IsoDateTime.d.ts index 807102067df..ffa3aa612bb 100644 --- a/ffi/capi/bindings/js/IsoDateTime.d.ts +++ b/ffi/capi/bindings/js/IsoDateTime.d.ts @@ -26,18 +26,12 @@ export class IsoDateTime { static fromString(v: string): IsoDateTime; - static localUnixEpoch(): IsoDateTime; - - static fromMinutesSinceLocalUnixEpoch(minutes: number): IsoDateTime; - get date(): IsoDate; get time(): Time; toAny(): DateTime; - get minutesSinceLocalUnixEpoch(): number; - toCalendar(calendar: Calendar): DateTime; get hour(): number; diff --git a/ffi/capi/bindings/js/IsoDateTime.mjs b/ffi/capi/bindings/js/IsoDateTime.mjs index 23942247692..1b2d8161620 100644 --- a/ffi/capi/bindings/js/IsoDateTime.mjs +++ b/ffi/capi/bindings/js/IsoDateTime.mjs @@ -99,26 +99,6 @@ export class IsoDateTime { } } - static localUnixEpoch() { - const result = wasm.icu4x_IsoDateTime_local_unix_epoch_mv1(); - - try { - return new IsoDateTime(diplomatRuntime.internalConstructor, result, []); - } - - finally {} - } - - static fromMinutesSinceLocalUnixEpoch(minutes) { - const result = wasm.icu4x_IsoDateTime_from_minutes_since_local_unix_epoch_mv1(minutes); - - try { - return new IsoDateTime(diplomatRuntime.internalConstructor, result, []); - } - - finally {} - } - get date() { const result = wasm.icu4x_IsoDateTime_date_mv1(this.ffiValue); @@ -149,16 +129,6 @@ export class IsoDateTime { finally {} } - get minutesSinceLocalUnixEpoch() { - const result = wasm.icu4x_IsoDateTime_minutes_since_local_unix_epoch_mv1(this.ffiValue); - - try { - return result; - } - - finally {} - } - toCalendar(calendar) { const result = wasm.icu4x_IsoDateTime_to_calendar_mv1(this.ffiValue, calendar.ffiValue); diff --git a/ffi/capi/src/date.rs b/ffi/capi/src/date.rs index ba54b857caf..1849c054b24 100644 --- a/ffi/capi/src/date.rs +++ b/ffi/capi/src/date.rs @@ -53,13 +53,6 @@ pub mod ffi { Ok(Box::new(IsoDate(icu_calendar::Date::try_iso_from_utf8(v)?))) } - /// Creates a new [`IsoDate`] representing January 1, 1970. - #[diplomat::rust_link(icu::calendar::Date::unix_epoch, FnInStruct)] - #[diplomat::attr(supports = fallible_constructors, named_constructor)] - pub fn unix_epoch() -> Box { - Box::new(IsoDate(icu_calendar::Date::unix_epoch())) - } - /// Convert this date to one in a different calendar #[diplomat::rust_link(icu::calendar::Date::to_calendar, FnInStruct)] pub fn to_calendar(&self, calendar: &Calendar) -> Box { diff --git a/ffi/capi/src/datetime.rs b/ffi/capi/src/datetime.rs index cf6dd7e0af6..113500303fe 100644 --- a/ffi/capi/src/datetime.rs +++ b/ffi/capi/src/datetime.rs @@ -63,26 +63,6 @@ pub mod ffi { ))) } - /// Creates a new [`IsoDateTime`] of midnight on January 1, 1970 - #[diplomat::rust_link(icu::calendar::DateTime::local_unix_epoch, FnInStruct)] - #[diplomat::attr(supports = fallible_constructors, named_constructor)] - pub fn local_unix_epoch() -> Box { - let dt = icu_calendar::DateTime::local_unix_epoch(); - Box::new(IsoDateTime(dt)) - } - - /// Construct from the minutes since the local unix epoch for this date (Jan 1 1970, 00:00) - #[diplomat::rust_link( - icu::calendar::DateTime::from_minutes_since_local_unix_epoch, - FnInStruct - )] - #[diplomat::attr(supports = fallible_constructors, named_constructor)] - pub fn from_minutes_since_local_unix_epoch(minutes: i32) -> Box { - Box::new(IsoDateTime( - icu_calendar::DateTime::from_minutes_since_local_unix_epoch(minutes), - )) - } - /// Gets the date contained in this object #[diplomat::rust_link(icu::calendar::DateTime::date, StructField)] #[diplomat::attr(auto, getter)] @@ -105,13 +85,6 @@ pub mod ffi { Box::new(DateTime(self.0.to_any().wrap_calendar_in_arc())) } - /// Gets the minutes since the local unix epoch for this date (Jan 1 1970, 00:00) - #[diplomat::rust_link(icu::calendar::DateTime::minutes_since_local_unix_epoch, FnInStruct)] - #[diplomat::attr(auto, getter)] - pub fn minutes_since_local_unix_epoch(&self) -> i32 { - self.0.minutes_since_local_unix_epoch() - } - /// Convert this datetime to one in a different calendar #[diplomat::rust_link(icu::calendar::DateTime::to_calendar, FnInStruct)] pub fn to_calendar(&self, calendar: &Calendar) -> Box { diff --git a/provider/source/src/time_zones/convert.rs b/provider/source/src/time_zones/convert.rs index 23c3e1c460c..a28d06f312e 100644 --- a/provider/source/src/time_zones/convert.rs +++ b/provider/source/src/time_zones/convert.rs @@ -7,8 +7,9 @@ use crate::SourceDataProvider; use cldr_serde::time_zones::meta_zones::MetaLocationOrSubRegion; use cldr_serde::time_zones::meta_zones::ZonePeriod; use cldr_serde::time_zones::time_zone_names::*; -use icu::calendar::DateTime; +use icu::calendar::Date; use icu::calendar::Iso; +use icu::calendar::Time; use icu::datetime::provider::time_zones::*; use icu::timezone::provider::*; use icu::timezone::UtcOffset; @@ -259,8 +260,12 @@ impl DataProvider for SourceDataProvider { .from .as_deref() .map(parse_mzone_from) - .unwrap_or(DateTime::try_new_iso(1970, 1, 1, 0, 0, 0).unwrap()) - .minutes_since_local_unix_epoch(), + .map(|(date, time)| { + (date.to_fixed() - EPOCH) as i32 * 24 * 60 + + (time.hour.number() as i32 * 60 + + time.minute.number() as i32) + }) + .unwrap_or_default(), meta_zone_id_data.get(&period.uses_meta_zone.mzone).copied(), )) }) @@ -312,6 +317,10 @@ impl DataProvider for SourceDataProvider { for zone_info in zoneset.iter() { let local_end_time = zone_info .end_time + // WARNING: This produces a *local* timestamp, i.e. seconds since 1970-01-01 00:00:00 *wall time*, + // even though the docs say that this is since the UNIX epoch (i.e. 1970-01-01 00:00:00 UTC). + // This also assumes `t` uses the same offset as 1970-01-01 00:00:00. + // While the local timestamps are what we want, the offset assumption probably needs fixing (TODO). .map(|t| (t.to_timestamp() / 60) as IsoMinutesSinceEpoch) .unwrap_or(IsoMinutesSinceEpoch::MAX); @@ -632,7 +641,7 @@ fn convert_cldr_zone_variant( }) } -fn parse_mzone_from(from: &str) -> DateTime { +fn parse_mzone_from(from: &str) -> (Date, Time) { // TODO(#2127): Ideally this parsing can move into a library function let parts: Vec = from.split(' ').map(|s| s.to_string()).collect(); let date = &parts[0]; @@ -644,5 +653,8 @@ fn parse_mzone_from(from: &str) -> DateTime { let time_parts: Vec = time.split(':').map(|s| s.to_string()).collect(); let hour = time_parts[0].parse::().unwrap(); let minute = time_parts[1].parse::().unwrap(); - DateTime::try_new_iso(year, month, day, hour, minute, 0).unwrap() + ( + Date::try_new_iso(year, month, day).unwrap(), + Time::try_new(hour, minute, 0, 0).unwrap(), + ) }