#![allow(dead_code, unused)]
use core::str;
use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
use std::convert::From;
use time::{format_description, OffsetDateTime};
use crate::{check, Microseconds, TimePoint};
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)]
pub struct TimePointSec {
pub utc_seconds: u32,
}
impl TimePointSec {
pub fn new() -> TimePointSec {
TimePointSec { utc_seconds: 0 }
}
pub fn maximum() -> TimePointSec {
TimePointSec { utc_seconds: 0xffffffff }
}
pub fn min() -> TimePointSec {
TimePointSec { utc_seconds: 0 }
}
pub fn sec_since_epoch(&self) -> u32 {
self.utc_seconds
}
pub fn from_iso_string(str: &str) -> Self {
let dt = OffsetDateTime::parse(format!("{str}Z").as_str(), &format_description::well_known::Iso8601::DEFAULT)
.expect("date parsing failed");
TimePointSec::from(dt.unix_timestamp() as u32)
}
}
impl From<u32> for TimePointSec {
fn from(seconds: u32) -> Self {
TimePointSec { utc_seconds: seconds }
}
}
impl From<TimePoint> for TimePointSec {
fn from(tp: TimePoint) -> Self {
TimePointSec::from(tp.sec_since_epoch())
}
}
impl std::fmt::Display for TimePointSec {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let dt = OffsetDateTime::from_unix_timestamp(self.sec_since_epoch() as i64).expect("format failed");
let format = format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]").unwrap();
write!(f, "{}", dt.format(&format).unwrap())
}
}
impl std::ops::AddAssign for TimePointSec {
fn add_assign(&mut self, other: Self) {
self.utc_seconds += other.utc_seconds;
}
}
impl std::ops::AddAssign<Microseconds> for TimePointSec {
fn add_assign(&mut self, other: Microseconds) {
self.utc_seconds += other.to_seconds() as u32;
}
}
impl std::ops::AddAssign<u32> for TimePointSec {
fn add_assign(&mut self, other: u32) {
self.utc_seconds += other;
}
}
impl std::ops::SubAssign for TimePointSec {
fn sub_assign(&mut self, other: Self) {
self.utc_seconds -= other.utc_seconds;
}
}
impl std::ops::SubAssign<Microseconds> for TimePointSec {
fn sub_assign(&mut self, other: Microseconds) {
self.utc_seconds -= other.to_seconds() as u32;
}
}
impl std::ops::SubAssign<u32> for TimePointSec {
fn sub_assign(&mut self, other: u32) {
self.utc_seconds -= other;
}
}
impl std::ops::Add<Microseconds> for TimePointSec {
type Output = Self;
fn add(self, other: Microseconds) -> Self {
let mut result = self;
result += other;
result
}
}
impl std::ops::Add<u32> for TimePointSec {
type Output = Self;
fn add(self, other: u32) -> Self {
let mut result = self;
result += other;
result
}
}
impl std::ops::Sub<u32> for TimePointSec {
type Output = Self;
fn sub(self, other: u32) -> Self {
let mut result = self;
result -= other;
result
}
}
impl std::ops::Sub<Microseconds> for TimePointSec {
type Output = Self;
fn sub(self, other: Microseconds) -> Self {
let mut result = self;
result -= other;
result
}
}
impl std::ops::Sub for TimePointSec {
type Output = Self;
fn sub(self, other: Self) -> Self {
let mut result = self;
result -= other;
result
}
}
#[cfg(test)]
mod tests {
use crate::seconds;
use super::*;
#[test]
fn test_new() {
let time_point = TimePointSec::new();
assert_eq!(time_point.utc_seconds, 0);
}
#[test]
fn test_maximum() {
let time_point = TimePointSec::maximum();
assert_eq!(time_point.utc_seconds, 0xffffffff);
}
#[test]
fn test_min() {
let time_point = TimePointSec::min();
assert_eq!(time_point.utc_seconds, 0);
}
#[test]
fn test_partial_eq() {
let time_point1 = TimePointSec { utc_seconds: 123 };
let time_point2 = TimePointSec { utc_seconds: 123 };
let time_point3 = TimePointSec { utc_seconds: 456 };
assert_eq!(time_point1, time_point2);
assert_ne!(time_point1, time_point3);
}
#[test]
fn test_partial_ord() {
let time_point1 = TimePointSec { utc_seconds: 123 };
let time_point2 = TimePointSec { utc_seconds: 456 };
let time_point3 = TimePointSec { utc_seconds: 789 };
assert!(time_point1 < time_point2);
assert!(time_point2 > time_point1);
assert!(time_point3 > time_point2);
}
#[test]
fn test_eq() {
let time_point1 = TimePointSec { utc_seconds: 123 };
let time_point2 = TimePointSec { utc_seconds: 123 };
let time_point3 = TimePointSec { utc_seconds: 456 };
assert_eq!(time_point1.eq(&time_point2), true);
assert_eq!(time_point1.eq(&time_point3), false);
}
#[test]
fn test_cmp() {
let time_point1 = TimePointSec { utc_seconds: 123 };
let time_point2 = TimePointSec { utc_seconds: 456 };
let time_point3 = TimePointSec { utc_seconds: 789 };
assert_eq!(time_point1.cmp(&time_point2), Ordering::Less);
assert_eq!(time_point2.cmp(&time_point1), Ordering::Greater);
assert_eq!(time_point2.cmp(&time_point3), Ordering::Less);
}
#[test]
fn test_from_iso_string() {
assert_eq!(TimePointSec::from_iso_string("1970-01-01T00:00:00").sec_since_epoch(), 0);
assert_eq!(TimePointSec::from_iso_string("1998-06-15T08:13:12").sec_since_epoch(), 897898392);
assert_eq!(TimePointSec::from_iso_string("2020-01-01T00:00:00").sec_since_epoch(), 1577836800);
assert_eq!(TimePointSec::from_iso_string("2038-01-19T03:14:07").sec_since_epoch(), 2147483647);
}
#[test]
fn test_to_iso_string() {
assert_eq!(
TimePointSec::from_iso_string("1970-01-01T00:00:00").to_string(),
"1970-01-01T00:00:00"
);
assert_eq!(
TimePointSec::from_iso_string("1998-06-15T08:13:12").to_string(),
"1998-06-15T08:13:12"
);
assert_eq!(
TimePointSec::from_iso_string("2020-01-01T00:00:00").to_string(),
"2020-01-01T00:00:00"
);
assert_eq!(
TimePointSec::from_iso_string("2038-01-19T03:14:07").to_string(),
"2038-01-19T03:14:07"
);
}
#[test]
#[should_panic]
fn test_iso_string_panic() {
TimePointSec::from_iso_string("invalid_string");
}
#[test]
#[should_panic]
fn test_iso_string_panic2() {
TimePointSec::from_iso_string("2010-13-81T00:00:00");
}
#[test]
fn test_add_assign_self() {
let mut tp1 = TimePointSec::from(100u32);
let tp2 = TimePointSec::from(50u32);
tp1 += tp2;
assert_eq!(tp1.sec_since_epoch(), 150);
}
#[test]
fn test_add_assign_ms() {
let mut tp = TimePointSec::from(100);
let elapsed = Microseconds::from(50_000_000);
tp += elapsed;
assert_eq!(tp.sec_since_epoch(), 150);
}
#[test]
fn test_add_assign_u32() {
let mut tp1 = TimePointSec::from(100);
tp1 += 50u32;
assert_eq!(tp1.sec_since_epoch(), 150);
}
#[test]
fn test_sub_assign_self() {
let mut tp1 = TimePointSec::from(100u32);
let tp2 = TimePointSec::from(50u32);
tp1 -= tp2;
assert_eq!(tp1.sec_since_epoch(), 50);
}
#[test]
fn test_sub_assign_ms() {
let mut tp = TimePointSec::from(100);
let elapsed = Microseconds::from(50_000_000);
tp -= elapsed;
assert_eq!(tp.sec_since_epoch(), 50);
}
#[test]
fn test_sub_assign_u32() {
let mut tp1 = TimePointSec::from(100);
tp1 -= 50u32;
assert_eq!(tp1.sec_since_epoch(), 50);
}
#[test]
fn test_add_s() {
let tp1 = TimePointSec::from(100);
let tp2 = tp1 + 50;
assert_eq!(tp2.sec_since_epoch(), 150);
}
#[test]
fn test_add_ms() {
let tp1 = TimePointSec::from(100);
let tp2 = tp1 + Microseconds::from(50_000_000);
assert_eq!(tp2.sec_since_epoch(), 150);
}
#[test]
fn test_sub_self() {
let tp1 = TimePointSec::from(100);
let tp2 = TimePointSec::from(50);
assert_eq!((tp1 - tp2).sec_since_epoch(), 50);
}
#[test]
fn test_sub_s() {
let tp1 = TimePointSec::from(100);
assert_eq!((tp1 - 50).sec_since_epoch(), 50);
}
#[test]
fn test_sub_ms() {
let tp1 = TimePointSec::from(100);
assert_eq!((tp1 - Microseconds::from(50_000_000)).sec_since_epoch(), 50);
}
}