Processing dates and times with Rust and chrono
Yesterday, we looked at a few date calculations in Perl. Here are the same calculations in Rust using the chrono crate.
use chrono::{Datelike, Duration, TimeZone};
fn main() {
let now = chrono::Local::now();
// Finding the date in 10 days time
println!("{}", now + Duration::days(10));
// Finding the date of the previous Saturday
let days = 1 + now.date().weekday().num_days_from_sunday();
println!("{}", now - Duration::days(days as i64));
// Finding the date of the first Monday in a given year
let first_doy = chrono::Local.ymd(now.year(), 1, 1).and_hms(0, 0, 0);
let days = (8 - first_doy.date().weekday().num_days_from_sunday()) % 7;
println!("{}", first_doy + Duration::days(days as i64));
}
One issue with the original post was that Time::Piece's day_of_week
gives 0..6
starting from Sunday, while DateTime's day_of_week
gives 1..7
starting from Monday (so that DateTime calcuation is wrong on Sundays: it will back up 8 days instead of 1). Rather than day_of_week
, chrono supplies a number of methods to choose from: we used num_days_from_sunday
above. As with many things in Rust, we are forced to be explicit.
Note that running this here and now (2021-11-12 08:46:04.487898162 -05:00) gives
❯ cargo run -q
2021-11-22 08:46:04.487898162 -05:00
2021-11-06 09:46:04.487898162 -04:00
2021-01-04 00:00:00 -05:00
We moved the clocks back from Daylight Saving Time to Standard Time on Sunday, so last Saturday was a different offset!
One of the nice suprises with Rust is that, despite its being a "low-level" programming language (like C), it has some nice affordances for "higher-level" programming (like Perl).