time: take in account the local tz

This commit is contained in:
Sylvestre Ledru 2022-04-24 09:51:15 +02:00
parent 326dc5080d
commit 10eaaae272
2 changed files with 41 additions and 5 deletions

View file

@ -13,6 +13,7 @@
extern crate time;
use time::macros::format_description;
use time::UtcOffset;
pub use crate::*; // import macros from `../../macros.rs`
@ -733,16 +734,36 @@ where
}
// match strftime "%Y-%m-%d %H:%M:%S.%f %z"
const PRETTY_DATETIME_FORMAT: &[time::format_description::FormatItem] = format_description!("[year]-[month]-[day padding:zero] [hour]:[minute]:[second].[subsecond] [offset_hour sign:mandatory][offset_minute]");
const PRETTY_DATETIME_FORMAT: &[time::format_description::FormatItem] = format_description!("[year]-[month]-[day padding:zero] [hour]:[minute]:[second].[subsecond digits:9] [offset_hour sign:mandatory][offset_minute]");
pub fn pretty_time(sec: i64, nsec: i64) -> String {
// sec == seconds since UNIX_EPOCH
// nsec == nanoseconds since (UNIX_EPOCH + sec)
let ts_nanos: i128 = (sec * 1_000_000_000 + nsec).into();
// TODO: return errors to caller
let tm = time::OffsetDateTime::from_unix_timestamp_nanos(ts_nanos).unwrap();
let res = tm.format(&PRETTY_DATETIME_FORMAT).unwrap();
// Return the date in UTC
let tm = match time::OffsetDateTime::from_unix_timestamp_nanos(ts_nanos) {
Ok(tm) => tm,
Err(e) => {
panic!("error: {}", e);
}
};
// Get the offset to convert to local time
// Because of DST (daylight saving), we get the local time back when
// the date was set
let local_offset = match UtcOffset::local_offset_at(tm) {
Ok(lo) => lo,
Err(e) => {
panic!("error: {}", e);
}
};
// Include the conversion to local time
let res = tm
.to_offset(local_offset)
.format(&PRETTY_DATETIME_FORMAT)
.unwrap();
if res.ends_with(" -0000") {
res.replace(" -0000", " +0000")
} else {

View file

@ -292,7 +292,22 @@ fn test_date() {
#[cfg(any(target_os = "linux", target_os = "android"))]
"%z",
#[cfg(target_os = "linux")]
"/dev/pts/ptmx",
"/bin/sh",
#[cfg(any(target_vendor = "apple"))]
"%z",
#[cfg(any(target_os = "android", target_vendor = "apple"))]
"/bin/sh",
];
let ts = TestScenario::new(util_name!());
let expected_stdout = unwrap_or_return!(expected_result(&ts, &args)).stdout_move_str();
ts.ucmd().args(&args).succeeds().stdout_is(expected_stdout);
// Just test the date for the time 0.3 change
let args = [
"-c",
#[cfg(any(target_os = "linux", target_os = "android"))]
"%z",
#[cfg(target_os = "linux")]
"/dev/ptmx",
#[cfg(any(target_vendor = "apple"))]
"%z",
#[cfg(any(target_os = "android", target_vendor = "apple"))]