What is the idiomatic way to get the duration between now and the next midnight?
I have a function like this:
extern crate chrono;
use chrono::prelude::*;
use time;
fn duration_until_next_midnight() -> time::Duration {
    let now = Local::now(); // Fri Dec 08 2017 23:00:00 GMT-0300 (-03)
    // ... how to continue??
}
It should make a Duration with 1 hour, since the next midnight is Sat Dec 09 2017 00:00:00 GMT-0300 (-03)
After scouring the docs, I finally found the missing link: Date::and_hms.
So, actually, it's as easy as:
fn main() {
    let now = Local::now();
    let tomorrow_midnight = (now + Duration::days(1)).date().and_hms(0, 0, 0);
    let duration = tomorrow_midnight.signed_duration_since(now).to_std().unwrap();
    println!("Duration between {:?} and {:?}: {:?}", now, tomorrow_midnight, duration);
}
The idea is simple:
DateTime to tomorrow,Date part, which keeps the timezone,DateTime by specifying a "00:00:00" Time with and_hms.There's a panic! in and_hms, so one has to be careful to specify a correct time.
Just subtract the two dates: midnight and now:
extern crate chrono;
use chrono::prelude::*;
use std::time;
fn duration_until_next_midnight() -> time::Duration {
    let now = Local::now();
    // change to next day and reset hour to 00:00
    let midnight = (now + chrono::Duration::days(1))
        .with_hour(0).unwrap()
        .with_minute(0).unwrap()
        .with_second(0).unwrap()
        .with_nanosecond(0).unwrap();
    println!("Duration between {:?} and {:?}:", now, midnight);
    midnight.signed_duration_since(now).to_std().unwrap()
}
fn main() {
    println!("{:?}", duration_until_next_midnight())
}
As requested by Matthieu, you can write something like:
fn duration_until_next_midnight() -> Duration {
    let now = Local::now();
    // get the NaiveDate of tomorrow
    let midnight_naivedate = (now + chrono::Duration::days(1)).naive_utc().date();
    // create a NaiveDateTime from it
    let midnight_naivedatetime = NaiveDateTime::new(midnight_naivedate, NaiveTime::from_hms(0, 0, 0));
    // get the local DateTime of midnight
    let midnight: DateTime<Local> = DateTime::from_utc(midnight_naivedatetime, *now.offset());
    println!("Duration between {:?} and {:?}:", now, midnight);
    midnight.signed_duration_since(now).to_std().unwrap()
}
But I am not sure if it is better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With