how to get the timestamp with timezone in rust - 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.

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.

Related

Convert UTC RFC3339 Timestamp to Local Time with the time crate

I've been banging my head against the time crate for the last two days. I can't find, where in their documentation how to take a RFC3339 UTC 2022-12-28T02:11:46Z timestamp and convert that to local time for America/New_York (2022-12-27T21:11:46). I stepped away from using the chrono crate on advise that there is/was a vulnerability and it's not very well maintained as it once was. Chrono also depends on time but in the 0.1.x branch of it.
My cargo.toml includes the line time = { version = "0.3", features = ["macros", "parsing", "local-offset"] } so enable the features I think I need.
use time::{format_description::well_known::Rfc3339, PrimitiveDateTime};
/// The paramater zulu would be a RFC3339 formatted string.
///
/// ```
/// #use time::{format_description::well_known::Rfc3339, PrimitiveDateTime};
/// assert_eq!("2022-12-27T21:11:46", date_time_local("2022-12-28T02:11:46Z".to_string()));
/// ```
fn date_time_local(zulu: &String) -> String {
match PrimitiveDateTime::parse(zulu, &Rfc3339) {
Ok(local) => local.to_string(),
Err(..) => zulu.to_owned(),
}
}
I'm having no such luck here.
fn main() {
assert_eq!("2022-12-27 21:11:46", date_time_local(&"2022-12-28T02:11:46Z".to_string()));
}
/// The parameter zulu should be a RFC3339 formatted string.
/// This converts that Zulu timestamp into a local timestamp.
/// ```
/// assert_eq!("2022-12-27 21:11:46", date_time_local("2022-12-28T02:11:46Z".to_string()));
/// ```
fn date_time_local(zulu: &String) -> String {
use time::{format_description::well_known::Rfc3339, PrimitiveDateTime, UtcOffset};
// Determine Local TimeZone
let utc_offset = match UtcOffset::current_local_offset() {
Ok(utc_offset) => utc_offset,
Err(..) => return zulu.to_owned(),
};
// Parse the given zulu paramater.
let zulu_parsed = match PrimitiveDateTime::parse(zulu, &Rfc3339) {
Ok(zulu_parsed) => zulu_parsed.assume_utc(),
Err(..) => return zulu.to_owned(),
};
// Convert zulu to local time offset.
let parsed = zulu_parsed.to_offset(utc_offset);
format!(
"{:04}-{:02}-{:02} {:02}:{:02}:{:02}",
parsed.year(),
parsed.month() as u8,
parsed.day(),
parsed.hour(),
parsed.minute(),
parsed.second()
)
}
With a slight change that I removed the T between the date and the time.

toLocaleString() not converting time to correct string

So I have the below code, which does a bunch of conversions between dates/strings/moments, and it all seems to be converting properly until the line that calls .toLocaleString(), not sure why but it is converting 2022-05-04T17:00:00.000Z to 5/4/2022, 1:00:00 PM, although I believe it should be 5/4/2022, 5:00:00 PM.
let timezone = "Europe/Lisbon"
let currentDate = new Date() // initialize new date object
let localizedTime = moment.tz(currentDate, timezone) // convert it to a moment in the specified timezone
localizedTime.set({ h: 18, m: 0, s: 0 }) // set the hours to 18 (equivalent to 6PM or 18:00)
let postgresFormat = localizedTime.format() // format in a postgres identifiable way
console.log(localizedTime.format())
let convertedBack = moment.tz(postgresFormat, timezone) // convert from string stored in Postgres back to a moment object
console.log(convertedBack)
let localedProperly = convertedBack.toDate() // convert from a moment to a Date object
console.log(localedProperly)
let withLocale = localedProperly.toLocaleString("en-US", { timezone: timezone }) // try to format it in such a way that a client can read it in 'en-US' locale. The local will change dynamically based on the user's device.
console.log(withLocale)
Not sure how to fix this, any help is much appreciated :)

Changing out rng as input to DH keying material

I am currently creating some DH keys using the x25519-dalek-ng crate for it.
Using rand_core I can create them like this, with the OSrng:
use x25519_dalek_ng::{self,PublicKey, StaticSecret};
use rand_core::{OsRng};
fn main() {
let i_dh_privkey : StaticSecret = StaticSecret::new(OsRng);
let i_dh_public_key = PublicKey::from(&i_dh_privkey);
}
But I want to change to a different rng, one that does not require a OS.
So I wanted to shift to rand_chacha.
I then tried doing this:
use x25519_dalek_ng::{self,PublicKey, StaticSecret};
use rand_chacha::{ChaCha8Rng};
fn main() {
let i_dh_privkey : StaticSecret = StaticSecret::new(ChaCha8Rng);
let i_dh_public_key = PublicKey::from(&i_dh_privkey);
}
And rust doesnt like this, and says:
help: use struct literal syntax instead'
Which I don't really udnerstand, both OSrng and ChaCha8Rng are structs.
StaticSecret::new() takes anything that implements crpytorng, should I do something to implement that for the chacha rng?

How to localize chrono days?

I have a code https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cde949e0a59445ee9beb01964a3ab903
use chrono::Datelike;
use chrono::Duration;
use chrono::Local;
fn main() {
let now = Local::now();
println!("######################################");
for day in 0..31 {
println!(
"{}",
(now + Duration::days(7 - now.weekday().num_days_from_monday() as i64 + day))
.format("%Y-%m-%d %A")
);
println!("\ntest\n\n########################");
}
}
Q: Where I need the weekdays to be in ex.: "HU" language and not in the English "Monday, Tuesday", etc.
I already tried based on https://docs.rs/chrono/0.4.19/chrono/ the ", Locale::hu_HU)" but always failed so far, can you pls help on this?
I think you need the feature unstable-locales for this. See here for the usage of format_localized.

Converting a UTC time via Timezones

I am displaying a date on the screen using the chrono crate.
The intention is to show the date in the users preferred time or UTC if no is set.
I have the UTC default set up, but I am unsure on the best method to record the user's timezone and how to apply that to the current date.
Note: date might not be set here so I'd prefer to modify date rather than use a different constructor.
let mut date: DateTime<UTC> = UTC::now();
//Convert to the User's Timezone if present
if let Some(user) = user {
//Extract the timezone
date.with_timezone(TimeZone::from_offset(&user.timezone));
}
let date_text = date.format("%H:%M %d/%m/%y").to_string();
What I would like is a type to use for user.timezone and an example on how to set the date.
You can use the chrono-tz crate, which allows you to convert a string to a timezone with chrono_tz::Tz::from_str("Europe/Berlin"). So all your user has to do is to supply a valid timezone string.
You can then use
fn date_time_str<Tz: chrono::TimeZone>(date: DateTime<Tz>, user: User) -> String {
if let Some(user) = user {
if let Ok(tz) = chrono_tz::Tz::from_str(user.timezone) {
let newdate = date.with_timezone(tz);
return newdate.format("%H:%M %d/%m/%y").to_string();
}
}
date.format("%H:%M %d/%m/%y").to_string()
}
You cannot modify the original date variable, because the types won't match. The timezone is part of the type. If you move completely to DateTime<chrono_tz::Tz>, then you could modify the variable, but all your uses of DateTime would need to be changed.

Resources