From 0235f9198fb856f4ec96c1c2be97bbccbf8fc268 Mon Sep 17 00:00:00 2001 From: Olle Sandberg Date: Mon, 3 Jun 2024 10:57:55 +0200 Subject: [PATCH] Do not use deprecated chrono types and functions --- rrule/src/iter/pos_list.rs | 9 +++--- rrule/src/iter/rrule_iter.rs | 20 +++++------- rrule/src/iter/utils.rs | 61 ++++++++++++++++++++++-------------- rrule/src/parser/datetime.rs | 3 +- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/rrule/src/iter/pos_list.rs b/rrule/src/iter/pos_list.rs index 458ad2b..da98d9c 100644 --- a/rrule/src/iter/pos_list.rs +++ b/rrule/src/iter/pos_list.rs @@ -1,4 +1,4 @@ -use super::utils::{add_time_to_date, from_ordinal, pymod}; +use super::utils::{add_time_to_date, date_from_ordinal, pymod}; use crate::core::{DateTime, Tz}; use chrono::NaiveTime; @@ -44,13 +44,12 @@ pub(crate) fn build_pos_list( let day = i64::try_from(*day) .expect("dayset is controlled by us and all elements are within range of i64"); - // Get ordinal which is UTC and apply timezone - let date = from_ordinal(year_ordinal + day).date().with_timezone(&tz); + // Get ordinal which is UTC + let date = date_from_ordinal(year_ordinal + day); // Create new Date + Time combination - // Use Date and Timezone from `date` // Use Time from `timeset`. let time = timeset[time_pos]; - let res = match add_time_to_date(date, time) { + let res = match add_time_to_date(tz, date, time) { Some(date) => date, None => continue, }; diff --git a/rrule/src/iter/rrule_iter.rs b/rrule/src/iter/rrule_iter.rs index 3c36c82..7195409 100644 --- a/rrule/src/iter/rrule_iter.rs +++ b/rrule/src/iter/rrule_iter.rs @@ -1,10 +1,9 @@ use super::counter_date::DateTimeIter; use super::utils::add_time_to_date; -use super::{build_pos_list, utils::from_ordinal, IterInfo, MAX_ITER_LOOP}; +use super::{build_pos_list, utils::date_from_ordinal, IterInfo, MAX_ITER_LOOP}; use crate::core::{get_hour, get_minute, get_second}; use crate::{core::DateTime, Frequency, RRule}; -use chrono::Datelike; -use chrono::{NaiveTime, TimeZone}; +use chrono::NaiveTime; use std::collections::VecDeque; #[derive(Debug, Clone)] @@ -124,6 +123,8 @@ impl<'a> RRuleIter<'a> { self.counter_date.day, ); + let tz = self.dt_start.timezone(); + if rrule.by_set_pos.is_empty() { // Loop over `start..end` for current_day in &dayset { @@ -133,17 +134,10 @@ impl<'a> RRuleIter<'a> { let year_ordinal = self.ii.year_ordinal(); // Ordinal conversion uses UTC: if we apply local-TZ here, then // just below we'll end up double-applying. - let date = from_ordinal(year_ordinal + current_day); - // We apply the local-TZ here. - let date = self - .dt_start - .timezone() - .ymd(date.year(), date.month(), date.day()); - + let date = date_from_ordinal(year_ordinal + current_day); for time in &self.timeset { - let dt = match add_time_to_date(date, *time) { - Some(dt) => dt, - None => continue, + let Some(dt) = add_time_to_date(tz, date, *time) else { + continue; }; if Self::try_add_datetime( dt, diff --git a/rrule/src/iter/utils.rs b/rrule/src/iter/utils.rs index 7f300a8..daeceb1 100644 --- a/rrule/src/iter/utils.rs +++ b/rrule/src/iter/utils.rs @@ -1,16 +1,15 @@ use std::ops; use crate::core::{duration_from_midnight, DateTime, Tz}; -use chrono::{Date, NaiveTime, TimeZone, Utc}; - -const UTC: Tz = Tz::UTC; +use chrono::{NaiveDate, NaiveTime, Utc}; const DAY_SECS: i64 = 24 * 60 * 60; -/// Converts number of days since unix epoch back to `DataTime` -pub(crate) fn from_ordinal(ordinal: i64) -> DateTime { - let timestamp = ordinal * DAY_SECS; - UTC.timestamp_opt(timestamp, 0).unwrap() +/// Converts number of days since unix epoch to a (naive) date. +pub(crate) fn date_from_ordinal(ordinal: i64) -> NaiveDate { + chrono::DateTime::::from_timestamp(ordinal * DAY_SECS, 0) + .unwrap() + .date_naive() } /// Returns number of days since unix epoch (rounded down) @@ -73,13 +72,13 @@ where } } -pub(crate) fn add_time_to_date(date: Date, time: NaiveTime) -> Option { - if let Some(dt) = date.and_time(time) { +pub(crate) fn add_time_to_date(tz: Tz, date: NaiveDate, time: NaiveTime) -> Option { + if let Some(dt) = date.and_time(time).and_local_timezone(tz).single() { return Some(dt); } - // If the day is a daylight saving time, the above code might now work, and we + // If the day is a daylight saving time, the above code might not work, and we // can try to get a valid datetime by adding the `time` as a duration instead. - let dt = date.and_hms_opt(0, 0, 0)?; + let dt = date.and_hms_opt(0, 0, 0)?.and_local_timezone(tz).single()?; let day_duration = duration_from_midnight(time); dt.checked_add_signed(day_duration) } @@ -87,10 +86,26 @@ pub(crate) fn add_time_to_date(date: Date, time: NaiveTime) -> Option = if flags.zulu_timezone_set { // If a `Z` is present, UTC should be used. - chrono::DateTime::::from_utc(datetime, chrono::Utc).with_timezone(&Tz::UTC) + chrono::DateTime::::from_naive_utc_and_offset(datetime, chrono::Utc) + .with_timezone(&Tz::UTC) } else { // If no `Z` is present, local time should be used. use chrono::offset::LocalResult;