I want to compare the current local time to a constant time range, but my current solution seems more difficult than I'd expect.
I can construct a chrono::DateTime<Local>
with Local::now()
. I can then laboriously find out if now
lies in a particular time range like so:
let current_hour = now.hour();
let current_minute = now.minute();
// see if `now` lies between 06:00 and 23:00
current_hour >= 6 && current_hour < 23
// note the inelegance of the syntax and the potential for fencepost errors
If I want to check the range from 06:12–23:15, the problem becomes much worse because I have to check if the hour is equal to 6 and then if the minutes are greater than 12 and then check — zzzzz...
That's boring. I can try string representations with parse_from_rfc2822
, but then I have to first emit the current date and then edit in the time of day and then check for parsing errors and now I'm sleeping again.
I imagine I'm just reading the chrono documentation wrong. If I were to implement the library, I would try to build a TimeOfDay<Local>
datatype which implements Ord
, thereby allowing idiomatic range checking. I figure it's already there somewhere and I'm just missing it.
DateTime
objects have a function called time()
, which returns a NaiveTime
object representing the time of day. NaiveTime
implements PartialOrd
, and has a factory function from_hms(hour, min, sec)
. Using from_hms
, you can create an upper bound and lower bound NaiveTime
, and then compare using standard operators.
let low = NaiveTime::from_hms(6, 12, 0);
let high = NaiveTime::from_hms(23, 15, 0);
let time_of_day = Local::now().time();
if (time_of_day > low) && (time_of_day < high) {
// do stuff...
} else {
// do something else...
};