Start adding defmt support #76

Merged
muellerr merged 3 commits from start-adding-defmt-support into main 2024-03-29 14:06:05 +01:00
4 changed files with 49 additions and 49 deletions
Showing only changes of commit 538548b05e - Show all commits

View File

@ -35,6 +35,7 @@ to check all the API changes in the **Changed** chapter.
- `UnixTimestamp` renamed to `UnixTime` - `UnixTimestamp` renamed to `UnixTime`
- `UnixTime` seconds are now private and can be retrieved using the `secs` member method. - `UnixTime` seconds are now private and can be retrieved using the `secs` member method.
- `UnixTime::new` renamed to `UnixTime::new_checked`. - `UnixTime::new` renamed to `UnixTime::new_checked`.
- `UnixTime::secs` renamed to `UnixTime::as_secs`.
- `UnixTime` now has a nanosecond subsecond precision. The `new` constructor now expects - `UnixTime` now has a nanosecond subsecond precision. The `new` constructor now expects
nanoseconds as the second argument. nanoseconds as the second argument.
- Added new `UnixTime::new_subsec_millis` and `UnixTime::new_subsec_millis_checked` API - Added new `UnixTime::new_subsec_millis` and `UnixTime::new_subsec_millis_checked` API
@ -47,6 +48,7 @@ to check all the API changes in the **Changed** chapter.
- Error handling for ECSS and time module is more granular now, with a new - Error handling for ECSS and time module is more granular now, with a new
`DateBeforeCcsdsEpochError` error and a `DateBeforeCcsdsEpoch` enum variant for both `DateBeforeCcsdsEpochError` error and a `DateBeforeCcsdsEpoch` enum variant for both
`CdsError` and `CucError`. `CdsError` and `CucError`.
- Time API `from_now*` API renamed to `now*`.
# [v0.11.0-rc.0] 2024-03-04 # [v0.11.0-rc.0] 2024-03-04

View File

@ -178,7 +178,7 @@ pub fn precision_from_pfield(pfield: u8) -> SubmillisPrecision {
/// use spacepackets::time::cds::{CdsTime, length_of_day_segment_from_pfield, LengthOfDaySegment}; /// use spacepackets::time::cds::{CdsTime, length_of_day_segment_from_pfield, LengthOfDaySegment};
/// use spacepackets::time::{TimeWriter, CcsdsTimeCode, CcsdsTimeProvider}; /// use spacepackets::time::{TimeWriter, CcsdsTimeCode, CcsdsTimeProvider};
/// ///
/// let timestamp_now = CdsTime::from_now_with_u16_days().unwrap(); /// let timestamp_now = CdsTime::now_with_u16_days().unwrap();
/// let mut raw_stamp = [0; 7]; /// let mut raw_stamp = [0; 7];
/// { /// {
/// let written = timestamp_now.write_to_bytes(&mut raw_stamp).unwrap(); /// let written = timestamp_now.write_to_bytes(&mut raw_stamp).unwrap();
@ -729,14 +729,14 @@ impl<ProvidesDaysLen: ProvidesDaysLength> CdsTime<ProvidesDaysLen> {
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn from_now_generic(days_len: LengthOfDaySegment) -> Result<Self, StdTimestampError> { fn now_generic(days_len: LengthOfDaySegment) -> Result<Self, StdTimestampError> {
let conversion_from_now = ConversionFromNow::new()?; let conversion_from_now = ConversionFromNow::new()?;
Self::generic_from_conversion(days_len, conversion_from_now) Self::generic_from_conversion(days_len, conversion_from_now)
.map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e))) .map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e)))
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn from_now_generic_us_prec(days_len: LengthOfDaySegment) -> Result<Self, StdTimestampError> { fn now_generic_with_us_prec(days_len: LengthOfDaySegment) -> Result<Self, StdTimestampError> {
let conversion_from_now = ConversionFromNow::new_with_submillis_us_prec()?; let conversion_from_now = ConversionFromNow::new_with_submillis_us_prec()?;
Self::generic_from_conversion(days_len, conversion_from_now) Self::generic_from_conversion(days_len, conversion_from_now)
.map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e))) .map_err(|e| StdTimestampError::Timestamp(TimestampError::from(e)))
@ -824,8 +824,8 @@ impl CdsTime<DaysLen24Bits> {
/// Generate a time stamp from the current time using the system clock. /// Generate a time stamp from the current time using the system clock.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u24_days() -> Result<Self, StdTimestampError> { pub fn now_with_u24_days() -> Result<Self, StdTimestampError> {
Self::from_now_generic(LengthOfDaySegment::Long24Bits) Self::now_generic(LengthOfDaySegment::Long24Bits)
} }
/// Create a provider from a [`chrono::DateTime<chrono::Utc>`] struct. /// Create a provider from a [`chrono::DateTime<chrono::Utc>`] struct.
@ -847,7 +847,7 @@ impl CdsTime<DaysLen24Bits> {
/// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS /// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS
/// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width /// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width
/// (24 bits). /// (24 bits).
pub fn from_unix_stamp_with_u24_days( pub fn from_unix_time_with_u24_day(
unix_stamp: &UnixTime, unix_stamp: &UnixTime,
submillis_prec: SubmillisPrecision, submillis_prec: SubmillisPrecision,
) -> Result<Self, CdsError> { ) -> Result<Self, CdsError> {
@ -870,16 +870,16 @@ impl CdsTime<DaysLen24Bits> {
Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Long24Bits) Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Long24Bits)
} }
/// Like [Self::from_now_with_u24_days] but with microsecond sub-millisecond precision. /// Like [Self::now_with_u24_days] but with microsecond sub-millisecond precision.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u24_days_us_precision() -> Result<Self, StdTimestampError> { pub fn now_with_u24_days_us_precision() -> Result<Self, StdTimestampError> {
Self::from_now_generic_us_prec(LengthOfDaySegment::Long24Bits) Self::now_generic_with_us_prec(LengthOfDaySegment::Long24Bits)
} }
/// Like [Self::from_now_with_u24_days] but with picoseconds sub-millisecond precision. /// Like [Self::now_with_u24_days] but with picoseconds sub-millisecond precision.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u24_days_ps_precision() -> Result<Self, StdTimestampError> { pub fn now_with_u24_days_ps_precision() -> Result<Self, StdTimestampError> {
Self::from_now_generic_us_prec(LengthOfDaySegment::Long24Bits) Self::now_generic_with_us_prec(LengthOfDaySegment::Long24Bits)
} }
pub fn from_bytes_with_u24_days(buf: &[u8]) -> Result<Self, TimestampError> { pub fn from_bytes_with_u24_days(buf: &[u8]) -> Result<Self, TimestampError> {
@ -928,8 +928,8 @@ impl CdsTime<DaysLen16Bits> {
/// Generate a time stamp from the current time using the system clock. /// Generate a time stamp from the current time using the system clock.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u16_days() -> Result<Self, StdTimestampError> { pub fn now_with_u16_days() -> Result<Self, StdTimestampError> {
Self::from_now_generic(LengthOfDaySegment::Short16Bits) Self::now_generic(LengthOfDaySegment::Short16Bits)
} }
/// Create a provider from a generic UNIX timestamp (seconds since 1970-01-01T00:00:00+00:00). /// Create a provider from a generic UNIX timestamp (seconds since 1970-01-01T00:00:00+00:00).
@ -939,7 +939,7 @@ impl CdsTime<DaysLen16Bits> {
/// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS /// This function will return [CdsError::DateBeforeCcsdsEpoch] if the time is before the CCSDS
/// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width /// epoch (1958-01-01T00:00:00+00:00) or the CCSDS days value exceeds the allowed bit width
/// (24 bits). /// (24 bits).
pub fn from_unix_stamp_with_u16_days( pub fn from_unix_time_with_u16_days(
unix_stamp: &UnixTime, unix_stamp: &UnixTime,
submillis_prec: SubmillisPrecision, submillis_prec: SubmillisPrecision,
) -> Result<Self, CdsError> { ) -> Result<Self, CdsError> {
@ -962,13 +962,13 @@ impl CdsTime<DaysLen16Bits> {
Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Short16Bits) Self::from_dt_generic_ps_prec(dt, LengthOfDaySegment::Short16Bits)
} }
/// Like [Self::from_now_with_u16_days] but with microsecond sub-millisecond precision. /// Like [Self::now_with_u16_days] but with microsecond sub-millisecond precision.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u16_days_us_precision() -> Result<Self, StdTimestampError> { pub fn now_with_u16_days_us_precision() -> Result<Self, StdTimestampError> {
Self::from_now_generic_us_prec(LengthOfDaySegment::Short16Bits) Self::now_generic_with_us_prec(LengthOfDaySegment::Short16Bits)
} }
/// Like [Self::from_now_with_u16_days] but with picosecond sub-millisecond precision. /// Like [Self::now_with_u16_days] but with picosecond sub-millisecond precision.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now_with_u16_days_ps_precision() -> Result<Self, StdTimestampError> { pub fn from_now_with_u16_days_ps_precision() -> Result<Self, StdTimestampError> {
Self::from_now_generic_ps_prec(LengthOfDaySegment::Short16Bits) Self::from_now_generic_ps_prec(LengthOfDaySegment::Short16Bits)
@ -1610,14 +1610,14 @@ mod tests {
#[test] #[test]
fn test_time_now() { fn test_time_now() {
let timestamp_now = CdsTime::from_now_with_u16_days().unwrap(); let timestamp_now = CdsTime::now_with_u16_days().unwrap();
let compare_stamp = chrono::Utc::now(); let compare_stamp = chrono::Utc::now();
generic_now_test(timestamp_now, compare_stamp); generic_now_test(timestamp_now, compare_stamp);
} }
#[test] #[test]
fn test_time_now_us_prec() { fn test_time_now_us_prec() {
let timestamp_now = CdsTime::from_now_with_u16_days_us_precision().unwrap(); let timestamp_now = CdsTime::now_with_u16_days_us_precision().unwrap();
let compare_stamp = chrono::Utc::now(); let compare_stamp = chrono::Utc::now();
generic_now_test(timestamp_now, compare_stamp); generic_now_test(timestamp_now, compare_stamp);
} }
@ -1638,7 +1638,7 @@ mod tests {
#[test] #[test]
fn test_time_now_ps_prec_u24_days() { fn test_time_now_ps_prec_u24_days() {
let timestamp_now = CdsTime::from_now_with_u24_days_ps_precision().unwrap(); let timestamp_now = CdsTime::now_with_u24_days_ps_precision().unwrap();
let compare_stamp = chrono::Utc::now(); let compare_stamp = chrono::Utc::now();
generic_now_test(timestamp_now, compare_stamp); generic_now_test(timestamp_now, compare_stamp);
} }
@ -1923,7 +1923,7 @@ mod tests {
fn test_creation_from_unix_stamp_0_u16_days() { fn test_creation_from_unix_stamp_0_u16_days() {
let unix_secs = 0; let unix_secs = 0;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = CdsTime::from_unix_stamp_with_u16_days( let time_provider = CdsTime::from_unix_time_with_u16_days(
&UnixTime::new(unix_secs, subsec_millis), &UnixTime::new(unix_secs, subsec_millis),
SubmillisPrecision::Absent, SubmillisPrecision::Absent,
) )
@ -1935,7 +1935,7 @@ mod tests {
fn test_creation_from_unix_stamp_0_u24_days() { fn test_creation_from_unix_stamp_0_u24_days() {
let unix_secs = 0; let unix_secs = 0;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = CdsTime::from_unix_stamp_with_u24_days( let time_provider = CdsTime::from_unix_time_with_u24_day(
&UnixTime::new(unix_secs, subsec_millis), &UnixTime::new(unix_secs, subsec_millis),
SubmillisPrecision::Absent, SubmillisPrecision::Absent,
) )
@ -1952,10 +1952,8 @@ mod tests {
.unwrap() .unwrap()
.and_local_timezone(chrono::Utc) .and_local_timezone(chrono::Utc)
.unwrap(); .unwrap();
let time_provider = CdsTime::from_unix_stamp_with_u16_days( let time_provider =
&datetime_utc.into(), CdsTime::from_unix_time_with_u16_days(&datetime_utc.into(), SubmillisPrecision::Absent)
SubmillisPrecision::Absent,
)
.expect("creating provider from unix stamp failed"); .expect("creating provider from unix stamp failed");
// https://www.timeanddate.com/date/durationresult.html?d1=01&m1=01&y1=1958&d2=14&m2=01&y2=2023 // https://www.timeanddate.com/date/durationresult.html?d1=01&m1=01&y1=1958&d2=14&m2=01&y2=2023
// Leap years need to be accounted for as well. // Leap years need to be accounted for as well.
@ -1972,7 +1970,7 @@ mod tests {
fn test_creation_0_ccsds_days() { fn test_creation_0_ccsds_days() {
let unix_secs = DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64; let unix_secs = DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64;
let subsec_millis = 0; let subsec_millis = 0;
let time_provider = CdsTime::from_unix_stamp_with_u16_days( let time_provider = CdsTime::from_unix_time_with_u16_days(
&UnixTime::new(unix_secs, subsec_millis), &UnixTime::new(unix_secs, subsec_millis),
SubmillisPrecision::Absent, SubmillisPrecision::Absent,
) )
@ -1984,7 +1982,7 @@ mod tests {
fn test_invalid_creation_from_unix_stamp_days_too_large() { fn test_invalid_creation_from_unix_stamp_days_too_large() {
let invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64; let invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64;
let subsec_millis = 0; let subsec_millis = 0;
match CdsTime::from_unix_stamp_with_u16_days( match CdsTime::from_unix_time_with_u16_days(
&UnixTime::new(invalid_unix_secs, subsec_millis), &UnixTime::new(invalid_unix_secs, subsec_millis),
SubmillisPrecision::Absent, SubmillisPrecision::Absent,
) { ) {
@ -2011,7 +2009,7 @@ mod tests {
// precisely 31-12-1957 23:59:55 // precisely 31-12-1957 23:59:55
let unix_secs = DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32 - 5; let unix_secs = DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32 - 5;
let subsec_millis = 0; let subsec_millis = 0;
match CdsTime::from_unix_stamp_with_u16_days( match CdsTime::from_unix_time_with_u16_days(
&UnixTime::new(unix_secs as i64, subsec_millis), &UnixTime::new(unix_secs as i64, subsec_millis),
SubmillisPrecision::Absent, SubmillisPrecision::Absent,
) { ) {
@ -2311,7 +2309,7 @@ mod tests {
#[test] #[test]
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
fn test_serialization() { fn test_serialization() {
let stamp_now = CdsTime::from_now_with_u16_days().expect("Error retrieving time"); let stamp_now = CdsTime::now_with_u16_days().expect("Error retrieving time");
let val = to_allocvec(&stamp_now).expect("Serializing timestamp failed"); let val = to_allocvec(&stamp_now).expect("Serializing timestamp failed");
assert!(val.len() > 0); assert!(val.len() > 0);
let stamp_deser: CdsTime = from_bytes(&val).expect("Stamp deserialization failed"); let stamp_deser: CdsTime = from_bytes(&val).expect("Stamp deserialization failed");

View File

@ -251,7 +251,7 @@ impl FractionalPart {
/// const LEAP_SECONDS: u32 = 37; /// const LEAP_SECONDS: u32 = 37;
/// ///
/// // Highest fractional resolution /// // Highest fractional resolution
/// let timestamp_now = CucTime::from_now(FractionalResolution::SixtyNs, LEAP_SECONDS) /// let timestamp_now = CucTime::now(FractionalResolution::SixtyNs, LEAP_SECONDS)
/// .expect("creating cuc stamp failed"); /// .expect("creating cuc stamp failed");
/// let mut raw_stamp = [0; 16]; /// let mut raw_stamp = [0; 16];
/// { /// {
@ -361,7 +361,7 @@ impl CucTime {
/// must be applied on top of the UTC based time retrieved from the system in addition to the /// must be applied on top of the UTC based time retrieved from the system in addition to the
/// conversion to the CCSDS epoch. /// conversion to the CCSDS epoch.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now( pub fn now(
fraction_resolution: FractionalResolution, fraction_resolution: FractionalResolution,
leap_seconds: u32, leap_seconds: u32,
) -> Result<Self, StdTimestampError> { ) -> Result<Self, StdTimestampError> {
@ -432,15 +432,15 @@ impl CucTime {
/// Generates a CUC timestamp from a UNIX timestamp with a width of 4. This width is able /// Generates a CUC timestamp from a UNIX timestamp with a width of 4. This width is able
/// to accomodate all possible UNIX timestamp values. /// to accomodate all possible UNIX timestamp values.
pub fn from_unix_stamp( pub fn from_unix_time(
unix_stamp: &UnixTime, unix_time: &UnixTime,
res: FractionalResolution, res: FractionalResolution,
leap_seconds: u32, leap_seconds: u32,
) -> Result<Self, CucError> { ) -> Result<Self, CucError> {
let counter = unix_epoch_to_ccsds_epoch(unix_stamp.secs); let counter = unix_epoch_to_ccsds_epoch(unix_time.secs);
// Negative CCSDS epoch is invalid. // Negative CCSDS epoch is invalid.
if counter < 0 { if counter < 0 {
return Err(DateBeforeCcsdsEpochError(*unix_stamp).into()); return Err(DateBeforeCcsdsEpochError(*unix_time).into());
} }
// We already excluded negative values, so the conversion to u64 should always work. // We already excluded negative values, so the conversion to u64 should always work.
let mut counter = u32::try_from(counter).map_err(|_| CucError::InvalidCounter { let mut counter = u32::try_from(counter).map_err(|_| CucError::InvalidCounter {
@ -451,7 +451,7 @@ impl CucTime {
.checked_add(leap_seconds) .checked_add(leap_seconds)
.ok_or(CucError::LeapSecondCorrectionError)?; .ok_or(CucError::LeapSecondCorrectionError)?;
let fractions = let fractions =
fractional_part_from_subsec_ns(res, unix_stamp.subsec_millis() as u64 * 10_u64.pow(6)); fractional_part_from_subsec_ns(res, unix_time.subsec_millis() as u64 * 10_u64.pow(6));
Self::new_generic(WidthCounterPair(4, counter as u32), fractions) Self::new_generic(WidthCounterPair(4, counter as u32), fractions)
} }
@ -915,7 +915,7 @@ mod tests {
#[test] #[test]
fn test_datetime_now() { fn test_datetime_now() {
let now = chrono::Utc::now(); let now = chrono::Utc::now();
let cuc_now = CucTime::from_now(FractionalResolution::SixtyNs, LEAP_SECONDS); let cuc_now = CucTime::now(FractionalResolution::SixtyNs, LEAP_SECONDS);
assert!(cuc_now.is_ok()); assert!(cuc_now.is_ok());
let cuc_now = cuc_now.unwrap(); let cuc_now = cuc_now.unwrap();
let ccsds_cuc = cuc_now.to_leap_sec_helper(LEAP_SECONDS); let ccsds_cuc = cuc_now.to_leap_sec_helper(LEAP_SECONDS);
@ -1253,6 +1253,7 @@ mod tests {
); );
assert_eq!(stamp.fractions().counter(), 0); assert_eq!(stamp.fractions().counter(), 0);
let res = stamp.update_from_now(LEAP_SECONDS); let res = stamp.update_from_now(LEAP_SECONDS);
assert!(res.is_ok()); assert!(res.is_ok());
} }
@ -1384,8 +1385,7 @@ mod tests {
#[test] #[test]
fn from_unix_stamp() { fn from_unix_stamp() {
let unix_stamp = UnixTime::new(0, 0); let unix_stamp = UnixTime::new(0, 0);
let cuc = let cuc = CucTime::from_unix_time(&unix_stamp, FractionalResolution::Seconds, LEAP_SECONDS)
CucTime::from_unix_stamp(&unix_stamp, FractionalResolution::Seconds, LEAP_SECONDS)
.expect("failed to create cuc from unix stamp"); .expect("failed to create cuc from unix stamp");
assert_eq!( assert_eq!(
cuc.counter(), cuc.counter(),

View File

@ -349,7 +349,7 @@ impl UnixTime {
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn from_now() -> Result<Self, SystemTimeError> { pub fn now() -> Result<Self, SystemTimeError> {
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
let epoch = now.as_secs(); let epoch = now.as_secs();
Ok(Self::new(epoch as i64, now.subsec_nanos())) Ok(Self::new(epoch as i64, now.subsec_nanos()))
@ -360,7 +360,7 @@ impl UnixTime {
self.secs as f64 + (self.subsec_nanos as f64 / 1_000_000_000.0) self.secs as f64 + (self.subsec_nanos as f64 / 1_000_000_000.0)
} }
pub fn secs(&self) -> i64 { pub fn as_secs(&self) -> i64 {
self.secs self.secs
} }
@ -371,7 +371,7 @@ impl UnixTime {
#[cfg(feature = "timelib")] #[cfg(feature = "timelib")]
pub fn timelib_date_time(&self) -> Result<time::OffsetDateTime, time::error::ComponentRange> { pub fn timelib_date_time(&self) -> Result<time::OffsetDateTime, time::error::ComponentRange> {
Ok(time::OffsetDateTime::from_unix_timestamp(self.secs())? Ok(time::OffsetDateTime::from_unix_timestamp(self.as_secs())?
+ time::Duration::nanoseconds(self.subsec_nanos().into())) + time::Duration::nanoseconds(self.subsec_nanos().into()))
} }
@ -653,7 +653,7 @@ mod tests {
fn test_addition() { fn test_addition() {
let mut stamp0 = UnixTime::new_only_secs(1); let mut stamp0 = UnixTime::new_only_secs(1);
stamp0 += Duration::from_secs(5); stamp0 += Duration::from_secs(5);
assert_eq!(stamp0.secs(), 6); assert_eq!(stamp0.as_secs(), 6);
assert_eq!(stamp0.subsec_millis(), 0); assert_eq!(stamp0.subsec_millis(), 0);
let stamp1 = stamp0 + Duration::from_millis(500); let stamp1 = stamp0 + Duration::from_millis(500);
assert_eq!(stamp1.secs, 6); assert_eq!(stamp1.secs, 6);
@ -682,7 +682,7 @@ mod tests {
#[test] #[test]
fn test_from_now() { fn test_from_now() {
let stamp_now = UnixTime::from_now().unwrap(); let stamp_now = UnixTime::now().unwrap();
let dt_now = stamp_now.chrono_date_time().unwrap(); let dt_now = stamp_now.chrono_date_time().unwrap();
assert!(dt_now.year() >= 2020); assert!(dt_now.year() >= 2020);
} }