Skip to content

Commit

Permalink
🐛 Fix Date::from_timestamp function
Browse files Browse the repository at this point in the history
  • Loading branch information
GiyoMoon committed Aug 25, 2022
1 parent d83ecc2 commit fd34508
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 29 deletions.
34 changes: 19 additions & 15 deletions src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub enum DateUnit {

/// Date in the proleptic Gregorian calendar.
///
/// Ranges from `30. June -5879611` to `12. July 5879611`. Please note that year 0 does not exist. After year -1 follows year 1.
/// Range: `30. June -5879611`..=`12. July 5879611`. Please note that year 0 does not exist. After year -1 follows year 1.
#[derive(Debug, Default, Copy, Clone, Eq)]
pub struct Date {
days: i32,
Expand Down Expand Up @@ -82,20 +82,24 @@ impl Date {
/// assert_eq!("1970/01/01", date.format("yyyy/MM/dd"));
/// ```
pub fn from_timestamp(timestamp: i64) -> Result<Self, AstrolabeError> {
let days = (timestamp / SECS_PER_DAY_U64 as i64 + DAYS_TO_1970_I64)
.try_into()
.map_err(|_| {
create_simple_oor(
"timestamp",
(i32::MIN as i128 - DAYS_TO_1970_I64 as i128) * SECS_PER_DAY_U64 as i128
- SECS_PER_DAY_U64 as i128
+ 1,
(i32::MAX as i128 - DAYS_TO_1970_I64 as i128) * SECS_PER_DAY_U64 as i128
+ SECS_PER_DAY_U64 as i128
- 1,
timestamp as i128,
)
})?;
let days = (timestamp / SECS_PER_DAY_U64 as i64 + DAYS_TO_1970_I64
- if timestamp.is_negative() && timestamp.unsigned_abs() % SECS_PER_DAY_U64 != 0 {
1
} else {
0
})
.try_into()
.map_err(|_| {
create_simple_oor(
"timestamp",
(i32::MIN as i128 - DAYS_TO_1970_I64 as i128) * SECS_PER_DAY_U64 as i128,
(i32::MAX as i128 - DAYS_TO_1970_I64 as i128) * SECS_PER_DAY_U64 as i128
+ SECS_PER_DAY_U64 as i128
- 1,
timestamp as i128,
)
})?;

Ok(Self { days })
}

Expand Down
2 changes: 1 addition & 1 deletion src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub enum DateTimeUnit {
/// Combined date and time.
/// Date is in the proleptic Gregorian calendar and clock time is with nanosecond precision.
///
/// Date ranges from `30. June -5879611` to `12. July 5879611`. Please note that year 0 does not exist. After year -1 follows year 1.
/// Range: `30. June -5879611 00:00:00`..=`12. July 5879611 23:59:59`. Please note that year 0 does not exist. After year -1 follows year 1.
#[derive(Debug, Default, Copy, Clone, Eq)]
pub struct DateTime {
days: i32,
Expand Down
14 changes: 11 additions & 3 deletions tests/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ mod date_tests {
#[test]
fn timestamp() {
assert_eq!(0, Date::from_timestamp(0).unwrap().timestamp());
assert_eq!(
"1970/01/01",
Date::from_timestamp(0).unwrap().format("yyyy/MM/dd")
);
assert_eq!(
"1969/12/31",
Date::from_timestamp(-1).unwrap().format("yyyy/MM/dd")
);
assert_eq!(
185_480_451_504_000,
Date::from_timestamp(185_480_451_590_399)
Expand All @@ -99,19 +107,19 @@ mod date_tests {

assert_eq!(
-185_604_722_784_000,
Date::from_timestamp(-185_604_722_870_399)
Date::from_timestamp(-185_604_722_784_000)
.unwrap()
.timestamp()
);
assert_eq!(
"-5879611/06/23",
Date::from_timestamp(-185_604_722_870_399)
Date::from_timestamp(-185_604_722_784_000)
.unwrap()
.format("yyyy/MM/dd")
);

assert!(Date::from_timestamp(185_480_451_590_400).is_err());
assert!(Date::from_timestamp(-185_604_722_870_400).is_err());
assert!(Date::from_timestamp(-185_604_722_784_001).is_err());
}

#[test]
Expand Down
44 changes: 34 additions & 10 deletions tests/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,26 @@ mod datetime_tests {
.unwrap()
.as_seconds()
);
assert_eq!(
"5879611/07/12 23:59:59",
DateTime::from_seconds(185_542_587_187_199)
.unwrap()
.format("yyyy/MM/dd HH:mm:ss")
);
assert!(DateTime::from_seconds(185_542_587_187_200).is_err());
assert_eq!(
-185_542_587_187_200,
DateTime::from_seconds(-185_542_587_187_200)
.unwrap()
.as_seconds()
);
assert!(DateTime::from_seconds(-185_542_587_273_600).is_err());
assert_eq!(
"-5879611/06/23 00:00:00",
DateTime::from_seconds(-185_542_587_187_200)
.unwrap()
.format("yyyy/MM/dd HH:mm:ss")
);
assert!(DateTime::from_seconds(-185_542_587_187_201).is_err());
}

#[test]
Expand All @@ -84,13 +96,25 @@ mod datetime_tests {
.unwrap()
.as_nanoseconds()
);
assert_eq!(
"5879611/07/12 23:59:59",
DateTime::from_nanoseconds(185_542_587_187_199_999_999_999)
.unwrap()
.format("yyyy/MM/dd HH:mm:ss")
);
assert!(DateTime::from_nanoseconds(185_542_587_187_200_000_000_000).is_err());
assert_eq!(
-185_542_587_187_200_000_000_000,
DateTime::from_nanoseconds(-185_542_587_187_200_000_000_000)
.unwrap()
.as_nanoseconds()
);
assert_eq!(
"-5879611/06/23 00:00:00",
DateTime::from_nanoseconds(-185_542_587_187_200_000_000_000)
.unwrap()
.format("yyyy/MM/dd HH:mm:ss")
);
assert!(DateTime::from_nanoseconds(-185_542_587_273_600_000_000_000).is_err());
}

Expand Down Expand Up @@ -231,33 +255,33 @@ mod datetime_tests {
fn timestamp() {
assert_eq!(0, DateTime::from_timestamp(0).unwrap().timestamp());
assert_eq!(
185480451504000,
DateTime::from_timestamp(185_480_451_504_000)
185_480_451_590_399,
DateTime::from_timestamp(185_480_451_590_399)
.unwrap()
.timestamp()
);
assert_eq!(
"5879611/07/12",
DateTime::from_timestamp(185_480_451_504_000)
"5879611/07/12 23:59:59",
DateTime::from_timestamp(185_480_451_590_399)
.unwrap()
.format("yyyy/MM/dd")
.format("yyyy/MM/dd HH:mm:ss")
);

assert_eq!(
-185604722784000,
-185_604_722_784_000,
DateTime::from_timestamp(-185_604_722_784_000)
.unwrap()
.timestamp()
);
assert_eq!(
"-5879611/06/23",
"-5879611/06/23 00:00:00",
DateTime::from_timestamp(-185_604_722_784_000)
.unwrap()
.format("yyyy/MM/dd")
.format("yyyy/MM/dd HH:mm:ss")
);

assert!(DateTime::from_timestamp(185_480_451_590_400).is_err());
assert!(DateTime::from_timestamp(-185_604_722_870_400).is_err());
assert!(DateTime::from_timestamp(-185_604_722_784_001).is_err());
}

#[test]
Expand Down

0 comments on commit fd34508

Please sign in to comment.