extern crate cron;
extern crate chrono;
extern crate chrono_tz;
use cron::Schedule;
use chrono::{ DateTime, TimeZone };
use std::str::FromStr;
pub fn next_ticks<Z>(schedule: &str, from_time: &DateTime<Z>, take: usize) -> Vec<DateTime::<Z>> where Z: TimeZone {
// sec min hour day of month month day of week year
// let expression = "0 30 9,12,15 1,15 May-Aug Mon,Wed,Fri 2018/2";
match Schedule::from_str(schedule) {
Ok(schedule) => schedule.after(from_time).take(take).collect::<Vec<DateTime::<Z>>>(),
Err(_e) => Vec::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::SecondsFormat;
use chrono_tz::Europe::Paris;
#[test]
fn test_time_zone_change_up() {
// During the night from the 28 to 29 march 2020, France has changed its time from 2am to 3am
// So when we reached "2020-03-29T02:00:00 Europe/Paris" we advanced to "2020-03-29T03:00:00 Europe/Paris"
let results = next_ticks("0 * * * * * *", &Paris.ymd(2020, 3, 29).and_hms(1, 55, 0), 10);
assert_eq!(results.len(), 10);
assert_eq!(results[0].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T01:56:00.000+01:00");
assert_eq!(results[1].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T01:57:00.000+01:00");
assert_eq!(results[2].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T01:58:00.000+01:00");
assert_eq!(results[3].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T01:59:00.000+01:00");
// Time zone shift here
assert_eq!(results[4].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:00:00.000+02:00");
assert_eq!(results[5].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:01:00.000+02:00");
assert_eq!(results[6].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:02:00.000+02:00");
assert_eq!(results[7].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:03:00.000+02:00");
assert_eq!(results[8].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:04:00.000+02:00");
assert_eq!(results[9].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-03-29T03:05:00.000+02:00");
}
#[test]
fn test_time_zone_change_down() {
// During the night from the 24 to 25 october 2020, France has changed its time from 3am to 2am
// So when we reached "2020-10-25T03:00:00 Europe/Paris" we went back to "2020-10-25T02:00:00 Europe/Paris"
let results = next_ticks("0 * * * * * *", &Paris.ymd(2020, 10, 25).and_hms(2, 55, 0), 1);
assert_eq!(results.len(), 10);
assert_eq!(results[0].to_rfc3339_opts(SecondsFormat::Millis, false), "2020-10-25T02:56:00.000+02:00");
}
}
The first works, the second test_time_zone_change_down panic with "thread 'tests::test_time_zone_change_down' panicked at 'invalid time', /Users/<>/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-0.4.19/src/date.rs:83:42"
Here is a small code to reproduce, note that I dont know precisely if the bug is in this project or
chrono_tz
...Cargo.toml:
Code:
The first works, the second
test_time_zone_change_down
panic with "thread 'tests::test_time_zone_change_down' panicked at 'invalid time', /Users/<>/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-0.4.19/src/date.rs:83:42"