diff options
-rw-r--r-- | src/rrule_iter.rs | 7 | ||||
-rw-r--r-- | tests/rrule.rs | 60 |
2 files changed, 66 insertions, 1 deletions
diff --git a/src/rrule_iter.rs b/src/rrule_iter.rs index 6f1af14..56dc456 100644 --- a/src/rrule_iter.rs +++ b/src/rrule_iter.rs @@ -5,6 +5,7 @@ use crate::{datetime::from_ordinal, RRule}; use crate::{datetime::Time, Frequenzy}; use chrono::{prelude::*, Duration}; use chrono_tz::Tz; +use chrono_tz::UTC; use std::collections::VecDeque; const MAX_YEAR: i32 = 9999; @@ -89,8 +90,12 @@ impl RRuleIter { } let current_day = current_day.unwrap(); + let year_ordinal = self.ii.yearordinal().unwrap(); + // Ordinal conversion uses UTC: if we apply local-TZ here, then + // just below we'll end up double-applying. let date = - from_ordinal(self.ii.yearordinal().unwrap() + current_day, &options.tzid); + from_ordinal(year_ordinal + current_day, &UTC); + // We apply the local-TZ here, let date = options.tzid.ymd(date.year(), date.month(), date.day()); for k in 0..self.timeset.len() { let res = date.and_hms(0, 0, 0) diff --git a/tests/rrule.rs b/tests/rrule.rs index 9308360..a7b60cb 100644 --- a/tests/rrule.rs +++ b/tests/rrule.rs @@ -9,6 +9,8 @@ use rrule::{Frequenzy, ParsedOptions, RRule}; #[cfg(test)] mod test { use super::*; + use rrule::Options; + use chrono::Weekday::Sat; fn ymd_hms( year: i32, @@ -6877,4 +6879,62 @@ mod test { ], ); } + + use chrono_tz::Europe::Berlin; + use chrono_tz::America::Los_Angeles; + use chrono_tz::America::New_York; + + #[test] + fn test_timezones_weekly() { + let rrule_options = Options::new() + .dtstart(UTC.ymd(2021, 1, 1).and_hms(9, 0, 0)) + .count(2) + .freq(Frequenzy::Weekly) + .byweekday(vec![Sat]) + .build() + .unwrap(); + let rrule = RRule::new(rrule_options.clone()); + for o in rrule.all().iter() { + assert_eq!(o.weekday(), Sat); + } + + // NYC (-5) + let rrule_options = Options::new() + .dtstart(New_York.ymd(2021, 1, 1).and_hms(9, 0, 0)) + .count(1) + .freq(Frequenzy::Weekly) + .byweekday(vec![Sat]) + .build() + .unwrap(); + let rrule = RRule::new(rrule_options.clone()); + for o in rrule.all().iter() { + assert_eq!(o.weekday(), Sat); + } + + // How about Berlin (+1) + let rrule_options = Options::new() + .dtstart(Berlin.ymd(2021, 1, 1).and_hms(9, 0, 0)) + .count(1) + .freq(Frequenzy::Weekly) + .byweekday(vec![Sat]) + .build() + .unwrap(); + let rrule = RRule::new(rrule_options.clone()); + for o in rrule.all().iter() { + assert_eq!(o.weekday(), Sat); + } + + // Los Angeles (-7) + let rrule_options = Options::new() + .dtstart(Los_Angeles.ymd(2021, 1, 1).and_hms(9, 0, 0)) + .count(1) + .freq(Frequenzy::Weekly) + .byweekday(vec![Sat]) + .build() + .unwrap(); + let rrule = RRule::new(rrule_options.clone()); + for o in rrule.all().iter() { + assert_eq!(o.weekday(), Sat); + } + } } |