ultimate-common 0.1.0

Rust libraries
Documentation
use std::sync::OnceLock;

pub use chrono::{DateTime, Duration, FixedOffset, Local, Utc};

use super::Result;

pub type OffsetDateTime = DateTime<FixedOffset>;
pub type UtcDateTime = DateTime<Utc>;

static LOCAL_OFFSET: OnceLock<FixedOffset> = OnceLock::new();

pub fn local_offset() -> &'static FixedOffset {
  LOCAL_OFFSET.get_or_init(_local_offset)
}

fn _local_offset() -> FixedOffset {
  FixedOffset::east_opt(3600 * 8).unwrap()
}

pub fn now_utc() -> OffsetDateTime {
  Utc::now().fixed_offset()
}

#[inline]
pub fn now() -> OffsetDateTime {
  Local::now().fixed_offset()
}

pub fn now_epoch_millis() -> i64 {
  let now = now_utc();
  now.timestamp_millis()
}

#[inline]
pub fn now_epoch_seconds() -> i64 {
  now_utc().timestamp()
}

pub fn format_time(time: OffsetDateTime) -> Result<String> {
  Ok(time.to_rfc3339())
}

pub fn now_utc_plus_sec_str(sec: u64) -> Result<String> {
  let new_time = now_utc() + Duration::seconds(sec as i64);
  format_time(new_time)
}

pub fn parse_utc(moment: &str) -> Result<OffsetDateTime> {
  let time = moment.parse::<OffsetDateTime>().unwrap();
  Ok(time)
}

#[cfg(feature = "prost-types")]
pub fn to_prost_timestamp(d: &OffsetDateTime) -> prost_types::Timestamp {
  prost_types::Timestamp { seconds: d.timestamp(), nanos: d.timestamp_subsec_nanos() as i32 }
}

#[cfg(feature = "prost-types")]
pub fn from_prost_timestamp(t: &prost_types::Timestamp) -> Option<OffsetDateTime> {
  DateTime::from_timestamp(t.seconds, t.nanos as u32).map(|d| d.fixed_offset())
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn test_now_utc() {
    let now = now_utc();
    assert_eq!(*now.offset(), FixedOffset::east_opt(0).unwrap());
  }

  #[test]
  fn test_convert_std() {
    let now_utc = now_utc();
    println!("now is: {}", now_utc);

    let now_local = now();
    println!("now is {}", now_local);
  }
}