Search code examples
rustrust-chrono

how to get the timestamp with timezone in rust


I am using this rust code to get the timestamp, but the time without time zone:

use std::time::Duration;
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, TimeZone, Utc};
use diesel::sql_types::Timestamptz;
use rust_wheel::common::util::time_util::get_current_millisecond;
use tokio::time;

#[tokio::main]
async fn main() {
    let trigger_time = (get_current_millisecond() - 35000)/1000;
    let time_without_zone = NaiveDateTime::from_timestamp( trigger_time ,0);
}

the timestamp result is 2022-08-30 13:00:15, the actual wanted result is: 2022-08-30 21:00:15. Then I tried to set the timezone:

use std::time::Duration;
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, TimeZone, Utc};
use diesel::sql_types::Timestamptz;
use rust_wheel::common::util::time_util::get_current_millisecond;
use tokio::time;

#[tokio::main]
async fn main() {
    let trigger_time = (get_current_millisecond() - 35000)/1000;
    let time_without_zone = NaiveDateTime::from_timestamp( trigger_time ,0);

    let tz_offset = FixedOffset::east(8 * 3600);
    let date_time: DateTime<Local> = Local.from_local_datetime(&time_without_zone).unwrap();
    print!("{}",date_time);

    let dt_with_tz: DateTime<FixedOffset> = tz_offset.from_local_datetime(&time_without_zone).unwrap();
    print!("{}",dt_with_tz);
}

the result is 2022-08-30 13:00:15 +08:00. is it possible to get the timestamp with the timezone? what should I do? I mean get the timestamp format like this 2022-08-30 21:00:15.


Solution

  • the result is 2022-08-30 13:00:15 +08:00. is it possible to get the timestamp with the timezone? what should I do? I mean get the timestamp format like this 2022-08-30 21:00:15.

    Your timestamp is (I assume) UTC, so that's what you should tell Chrono:

        let time_without_zone = NaiveDateTime::from_timestamp(timestamp, 0);
        // 2009-02-13 23:31:30
        let zoned: DateTime<FixedOffset> = DateTime::from_utc(time_without_zone, FixedOffset::east(8 * 3600));
        // 2009-02-14 07:31:30 +08:00
    

    Then you can use naive_local() to get a naive (timezone-less) view of the local time:

        zoned.naive_local()
        2009-02-14 07:31:30
    

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=941668e1e10930b0e9a6ede7e79fb0c1

    Warning: I'm not entirely sure naive_local() is the correct call, normally in chrono the "local" timezone is the timezone configured for the machine the program runs on (or something along those lines), but for naive_local it seems like chrono just applies the timezone and returns the result as a naive datetime. So it's what you want, but I find it a bit dubious. I can't find a better call tho.