Nth day of every Mth month in Rust

Viewed 110

I've been trying to find a crate to deal with complex time sequences. Using the excellent kronos crate, I can create TimeSequences like the "10th day of every month" or "the first Monday of every year" with NthOf and Grains().

// 10th day of every month
tenth_day = NthOf(10, Grains(Grain::Day), Grains(Grain::Month));

// 1st Monday of every year
first_monday = Nth(1, Weekday(1), Grains(Grain::Year));

But I want to do this for more complex TimeSequences, like "the 27th day of every other month". There are the Grain::Quarter and Grain::Half enum variants for every 3 and 6 months, respectively, but these are hard-coded and do not generalize to months that don't divide the year evenly, like every 5 months.

Is there a way I can get these more complex TimeSequences with kronos? Or is there another crate I could use for this problem?

1 Answers

After discussing with kronos' maintainer, using the step_by function or step_by method can make this work.

Here is an example with the step_by method on a Grains object.

use chrono::Datelike;

let mut every_3months_from_next_march_iter = Grains(Grain::Month)
    .future(&t0_april)
    .skip_while(|r| r.start.date().month() != 3)
    .step_by(3);
assert_eq!(
    every_3months_from_next_march_iter.next().unwrap(),
    Range{
        start: dt(2019, 3, 1),
        end: dt(2019, 4, 1), grain: Grain::Month
    }
);

And here is an example with the step_by function.

use kronos::{step_by, Grains, Grain, NthOf};

let third_day_every_5_months = NthOf(
    3,
    Grains(Grain::Day),
    step_by(Grains(Grain::Month), 5)
);
Related