Convert std::time::SystemTime to chrono::datetime::DateTime


#1

I’m building a tiny ls -al clone in Rust to get to know the language better. I managed to show the permissions and file names, now I want to display the timestamp for each directory entry. std::fs::Metadata has a modified function that returns a std::time::SystemTime (result). I now want to convert it into something that I can strftime :smile:

I asked that question on Twitter and got the recommendation to use chrono. But I don’t understand how to convert my std::time::SystemTime to a chrono::datetime::DateTime.

Any help is appreciated <3


#2

As the documentations says:

Although a SystemTime cannot be directly inspected, the UNIX_EPOCH constant is provided in this module as an anchor in time to learn information about a SystemTime. By calculating the duration from this fixed point in time, a SystemTime can be converted to a human-readable time

so you can do:

    use std::time::{Duration, SystemTime, UNIX_EPOCH};

    fn main() {
        let now = SystemTime::now();
        let seconds = now.duration_since(UNIX_EPOCH).unwrap().as_secs();
        println!("{}", seconds);
    }   

But the fact that SystemTime and Duration do not expose its fields just sucks. It causes only problems.


#3

If chrono does not yet feature From implementations for the stdlib types then perhaps this is a nice opportunity for a PR?


#4

For now, use the following: (Same for DateTime<Local>)

fn system_time_to_date_time(t: SystemTime) -> DateTime<UTC> {
    let (sec, nsec) = match t.duration_since(UNIX_EPOCH) {
        Ok(dur) => (dur.as_secs() as i64, dur.subsec_nanos()),
        Err(e) => { // unlikely but should be handled
            let dur = e.duration();
            let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos());
            if nsec == 0 {
                (-sec, 0)
            } else {
                (-sec - 1, 1_000_000_000 - nsec)
            }
        },
    };
    UTC.timestamp(sec, nsec)
}

Chrono 0.3 would switch to std::time::SystemTime and std::time::Duration for the primary timekeeping, so hopefully this workaround will be gone.


How to use System Constants : std::sys::time::UNIX_EPOCH
#5

Thanks to all of you :slight_smile: It works now! :slight_smile:

When I feel more comfortable with Rust, I’ll try to PR to chrono :wink: