From d09c5f76e22063ce4b149af4c95f9f0d0fe1011a Mon Sep 17 00:00:00 2001 From: baoyachi Date: Thu, 14 Jul 2022 01:27:52 +0800 Subject: [PATCH 1/6] add stash --- Cargo.toml | 2 ++ src/time.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c2a7600..203b867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,8 @@ all-features = true is_debug = "1.0.1" chrono = "0.4.13" const_format = "0.2.22" +tz-rs = "0.6.11" +time = {version="0.3.11",features=["formatting","local-offset"]} #! Optional Dependencies: diff --git a/src/time.rs b/src/time.rs index a0a7108..1713451 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,3 +1,4 @@ +use std::error::Error; use crate::Format; use chrono::{DateTime, Local, NaiveDateTime, SecondsFormat, TimeZone, Utc}; @@ -72,4 +73,56 @@ mod tests { let time = now_data_time(); assert_eq!(time.human_format(), "2021-08-04 12:34:03 +00:00"); } + + #[test] + fn test_local_now_human_format() { + let time = BuildTime::local_now().human_format(); + println!("{}",time);// 2022-07-14 00:40:05 +08:00 + + let current_utc_date_time = tz::UtcDateTime::now().unwrap(); + let date_time = current_utc_date_time.project(tz::TimeZone::local().unwrap().as_ref()).unwrap(); + println!("{}",tz_local_time_format(date_time).unwrap()); + assert_eq!(time,tz_local_time_format(date_time).unwrap()) + } +} + +use std::fmt::Write; +fn tz_local_time_format(date_time:tz::DateTime) -> std::result::Result>{ + let ut_offset = date_time.local_time_type().ut_offset(); + + /// Number of seconds in one minute + pub const SECONDS_PER_MINUTE: i64 = 60; + /// Number of minutes in one hour + pub const MINUTES_PER_HOUR: i64 = 60; + /// Number of seconds in one hour + pub const SECONDS_PER_HOUR: i64 = 3600; + + + let mut f = String::new(); + write!(f, "{}-{:02}-{:02} {:02}:{:02}:{:02} ", + date_time.year(), + date_time.month(), + date_time.month_day(), + date_time.hour(), + date_time.minute(), + date_time.second())?; + + if ut_offset != 0 { + let ut_offset = ut_offset as i64; + let ut_offset_abs = ut_offset.abs(); + + let offset_hour = ut_offset / SECONDS_PER_HOUR; + let offset_minute = (ut_offset_abs / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR; + let offset_second = ut_offset_abs % SECONDS_PER_MINUTE; + + write!(f, "{:+03}:{:02}", offset_hour, offset_minute)?; + + if offset_second != 0 { + write!(f, ":{:02}", offset_second)?; + } + } else { + write!(f, "Z")?; + } + Ok(f) } + From 77388b041e02a8ac80f93e839753bfbc234f9e97 Mon Sep 17 00:00:00 2001 From: baoyachi Date: Thu, 14 Jul 2022 01:38:01 +0800 Subject: [PATCH 2/6] add stash --- Cargo.toml | 2 +- src/time.rs | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 203b867..46c2587 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ is_debug = "1.0.1" chrono = "0.4.13" const_format = "0.2.22" tz-rs = "0.6.11" -time = {version="0.3.11",features=["formatting","local-offset"]} +time = {version="0.3.11",features=["formatting","local-offset","parsing"]} #! Optional Dependencies: diff --git a/src/time.rs b/src/time.rs index 1713451..0d96c9d 100644 --- a/src/time.rs +++ b/src/time.rs @@ -3,8 +3,14 @@ use crate::Format; use chrono::{DateTime, Local, NaiveDateTime, SecondsFormat, TimeZone, Utc}; pub enum BuildTime { - Local(DateTime), - Utc(DateTime), + Local(tz::DateTime), + Utc(time::OffsetDateTime), +} + +fn local_now() -> Result{ + let current_utc_date_time = tz::UtcDateTime::now()?; + let date_time = current_utc_date_time.project(tz::TimeZone::local().unwrap().as_ref())?; + Ok(date_time) } pub fn now_data_time() -> BuildTime { @@ -14,26 +20,27 @@ pub fn now_data_time() -> BuildTime { // https://reproducible-builds.org/docs/source-date-epoch/ println!("cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH"); match std::env::var_os("SOURCE_DATE_EPOCH") { - None => BuildTime::Local(Local::now()), + None => BuildTime::Local(local_now().unwrap()), Some(timestamp) => { let epoch = timestamp .into_string() .expect("Input SOURCE_DATE_EPOCH could not be parsed") .parse::() .expect("Input SOURCE_DATE_EPOCH could not be cast to a number"); - BuildTime::Utc(Utc.timestamp(epoch, 0)) + // BuildTime::Utc(Utc.timestamp(epoch, 0)) + BuildTime::Utc(OffsetDateTime::from_unix_timestamp(epoch).unwrap()) } } } impl BuildTime { pub fn local_now() -> Self { - BuildTime::Local(Local::now()) + BuildTime::Local(local_now().unwrap()) } pub fn timestamp_2_utc(time_stamp: i64) -> Self { - let dt = NaiveDateTime::from_timestamp(time_stamp, 0); - BuildTime::Utc(DateTime::::from_utc(dt, Utc)) + let time = OffsetDateTime::from_unix_timestamp(time_stamp).unwrap(); + BuildTime::Utc(time) } pub fn to_rfc2822(&self) -> String { @@ -87,6 +94,8 @@ mod tests { } use std::fmt::Write; +use time::OffsetDateTime; + fn tz_local_time_format(date_time:tz::DateTime) -> std::result::Result>{ let ut_offset = date_time.local_time_type().ut_offset(); From c9e35709d00cce5187dda0b31e123e0262f37d78 Mon Sep 17 00:00:00 2001 From: baoyachi Date: Fri, 15 Jul 2022 00:45:39 +0800 Subject: [PATCH 3/6] fix --- Cargo.toml | 1 - src/lib.rs | 4 ++- src/time.rs | 102 ++++++++++++++++------------------------------------ 3 files changed, 33 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 46c2587..ef05992 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,6 @@ all-features = true [dependencies] is_debug = "1.0.1" -chrono = "0.4.13" const_format = "0.2.22" tz-rs = "0.6.11" time = {version="0.3.11",features=["formatting","local-offset","parsing"]} diff --git a/src/lib.rs b/src/lib.rs index 0d73dbc..c3d2f7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -371,7 +371,9 @@ impl Shadow { // Author by:https://www.github.com/baoyachi // The build script repository:https://github.com/baoyachi/shadow-rs // Create time by:{}"#, - BuildTime::local_now().human_format() + BuildTime::local_now() + .map_err(|err| format!("get local DateTime error:{}", err))? + .human_format() ); writeln!(&self.f, "{}\n\n", desc)?; Ok(()) diff --git a/src/time.rs b/src/time.rs index 0d96c9d..e29eb2a 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,16 +1,14 @@ -use std::error::Error; use crate::Format; -use chrono::{DateTime, Local, NaiveDateTime, SecondsFormat, TimeZone, Utc}; +use std::error::Error; +use std::time::{SystemTime, UNIX_EPOCH}; +use time::format_description::well_known::{Rfc2822, Rfc3339}; +use time::UtcOffset; +use time::{format_description, OffsetDateTime}; +use tz::TimeZone; pub enum BuildTime { - Local(tz::DateTime), - Utc(time::OffsetDateTime), -} - -fn local_now() -> Result{ - let current_utc_date_time = tz::UtcDateTime::now()?; - let date_time = current_utc_date_time.project(tz::TimeZone::local().unwrap().as_ref())?; - Ok(date_time) + Local(OffsetDateTime), + Utc(OffsetDateTime), } pub fn now_data_time() -> BuildTime { @@ -20,7 +18,7 @@ pub fn now_data_time() -> BuildTime { // https://reproducible-builds.org/docs/source-date-epoch/ println!("cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH"); match std::env::var_os("SOURCE_DATE_EPOCH") { - None => BuildTime::Local(local_now().unwrap()), + None => BuildTime::local_now().unwrap(), Some(timestamp) => { let epoch = timestamp .into_string() @@ -34,8 +32,16 @@ pub fn now_data_time() -> BuildTime { } impl BuildTime { - pub fn local_now() -> Self { - BuildTime::Local(local_now().unwrap()) + pub fn local_now() -> Result> { + let time_zone_local = TimeZone::local()?; // expensive call, should be cached + + let duration_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH)?; + let local_time_type = + time_zone_local.find_local_time_type(duration_since_epoch.as_secs().try_into()?)?; + let time_zone_offset = UtcOffset::from_whole_seconds(local_time_type.ut_offset())?; + let local_date_time = + (OffsetDateTime::UNIX_EPOCH + duration_since_epoch).to_offset(time_zone_offset); + Ok(BuildTime::Local(local_date_time)) } pub fn timestamp_2_utc(time_stamp: i64) -> Self { @@ -45,27 +51,26 @@ impl BuildTime { pub fn to_rfc2822(&self) -> String { match self { - BuildTime::Local(dt) => dt.to_rfc2822(), - BuildTime::Utc(dt) => dt.to_rfc2822(), + BuildTime::Local(dt) | BuildTime::Utc(dt) => dt.format(&Rfc2822).unwrap(), } } pub fn to_rfc3339(&self) -> String { - let sec_form = SecondsFormat::Secs; - let use_z = true; match self { - BuildTime::Local(dt) => dt.to_rfc3339_opts(sec_form, use_z), - BuildTime::Utc(dt) => dt.to_rfc3339_opts(sec_form, use_z), + BuildTime::Local(dt) | BuildTime::Utc(dt) => dt.format(&Rfc3339).unwrap(), } } } impl Format for BuildTime { fn human_format(&self) -> String { - let fmt = "%Y-%m-%d %H:%M:%S %:z"; + let fmt = format_description::parse( + "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \ + sign:mandatory]:[offset_minute]", + ) + .unwrap(); match self { - BuildTime::Local(dt) => dt.format(fmt).to_string(), - BuildTime::Utc(dt) => dt.format(fmt).to_string(), + BuildTime::Local(dt) | BuildTime::Utc(dt) => dt.format(&fmt).unwrap(), } } } @@ -83,55 +88,8 @@ mod tests { #[test] fn test_local_now_human_format() { - let time = BuildTime::local_now().human_format(); - println!("{}",time);// 2022-07-14 00:40:05 +08:00 - - let current_utc_date_time = tz::UtcDateTime::now().unwrap(); - let date_time = current_utc_date_time.project(tz::TimeZone::local().unwrap().as_ref()).unwrap(); - println!("{}",tz_local_time_format(date_time).unwrap()); - assert_eq!(time,tz_local_time_format(date_time).unwrap()) - } -} - -use std::fmt::Write; -use time::OffsetDateTime; - -fn tz_local_time_format(date_time:tz::DateTime) -> std::result::Result>{ - let ut_offset = date_time.local_time_type().ut_offset(); - - /// Number of seconds in one minute - pub const SECONDS_PER_MINUTE: i64 = 60; - /// Number of minutes in one hour - pub const MINUTES_PER_HOUR: i64 = 60; - /// Number of seconds in one hour - pub const SECONDS_PER_HOUR: i64 = 3600; - - - let mut f = String::new(); - write!(f, "{}-{:02}-{:02} {:02}:{:02}:{:02} ", - date_time.year(), - date_time.month(), - date_time.month_day(), - date_time.hour(), - date_time.minute(), - date_time.second())?; - - if ut_offset != 0 { - let ut_offset = ut_offset as i64; - let ut_offset_abs = ut_offset.abs(); - - let offset_hour = ut_offset / SECONDS_PER_HOUR; - let offset_minute = (ut_offset_abs / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR; - let offset_second = ut_offset_abs % SECONDS_PER_MINUTE; - - write!(f, "{:+03}:{:02}", offset_hour, offset_minute)?; - - if offset_second != 0 { - write!(f, ":{:02}", offset_second)?; - } - } else { - write!(f, "Z")?; + let time = BuildTime::local_now().unwrap().human_format(); + println!("{}", time); // 2022-07-14 00:40:05 +08:00 + assert_eq!(time.len(), 26); } - Ok(f) } - From acd977efcbd1c185af77af2794894c774373811a Mon Sep 17 00:00:00 2001 From: baoyachi Date: Fri, 15 Jul 2022 00:58:15 +0800 Subject: [PATCH 4/6] add unit test --- Cargo.toml | 4 ++-- src/time.rs | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef05992..a244047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/baoyachi/shadow-rs" documentation = "https://docs.rs/shadow-rs" homepage = "https://github.com/baoyachi/shadow-rs" license = "MIT AND Apache-2.0" -exclude = ["shadow-rs.png","build_module.png"] +exclude = ["shadow-rs.png", "build_module.png"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -22,7 +22,7 @@ all-features = true is_debug = "1.0.1" const_format = "0.2.22" tz-rs = "0.6.11" -time = {version="0.3.11",features=["formatting","local-offset","parsing"]} +time = { version = "0.3.11", features = ["formatting", "local-offset", "parsing"] } #! Optional Dependencies: diff --git a/src/time.rs b/src/time.rs index e29eb2a..427212f 100644 --- a/src/time.rs +++ b/src/time.rs @@ -92,4 +92,12 @@ mod tests { println!("{}", time); // 2022-07-14 00:40:05 +08:00 assert_eq!(time.len(), 26); } + + #[test] + fn test_timestamp_2_utc() { + let time = BuildTime::timestamp_2_utc(1628080443); + assert_eq!(time.to_rfc2822(), "Wed, 04 Aug 2021 12:34:03 +0000"); + assert_eq!(time.to_rfc3339(), "2021-08-04T12:34:03Z"); + assert_eq!(time.human_format(), "2021-08-04 12:34:03 +00:00"); + } } From f0d78dfdd3361f54a84b9cd8b28001c673f714d3 Mon Sep 17 00:00:00 2001 From: baoyachi Date: Fri, 15 Jul 2022 01:13:58 +0800 Subject: [PATCH 5/6] upgrade shadow-rs#0.13.0 --- Cargo.toml | 2 +- src/lib.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a244047..629e1b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "shadow-rs" -version = "0.12.0" +version = "0.13.0" authors = ["baoyachi "] edition = "2021" description = "A build-time information stored in your rust project" diff --git a/src/lib.rs b/src/lib.rs index c3d2f7a..9ad8f51 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,6 +151,8 @@ mod gen_const; mod git; mod time; +pub use time::*; + /// Get current project build mode. /// /// It's very useful. Debug mode is usually used for debugging information. From 6f2d96d60134d2c9305e48d1b398b536eeac36af Mon Sep 17 00:00:00 2001 From: baoyachi Date: Fri, 15 Jul 2022 01:17:55 +0800 Subject: [PATCH 6/6] update --- src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9ad8f51..c3d2f7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,8 +151,6 @@ mod gen_const; mod git; mod time; -pub use time::*; - /// Get current project build mode. /// /// It's very useful. Debug mode is usually used for debugging information.