Skip to content

Commit

Permalink
Fix limit.js test and add datetime limit test
Browse files Browse the repository at this point in the history
  • Loading branch information
nekevss committed Jan 30, 2024
1 parent 8951d92 commit 9f59e52
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
43 changes: 43 additions & 0 deletions core/temporal/src/components/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,46 @@ impl<C: CalendarProtocol> FromStr for DateTime<C> {
))
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;

use crate::components::calendar::CalendarSlot;

use super::DateTime;

#[test]
#[allow(clippy::float_cmp)]
fn plain_date_time_limits() {
// This test is primarily to assert that the `expect` in the epoch methods is
// valid, i.e., a valid instant is within the range of an f64.
let negative_limit = DateTime::<()>::new(
-271821,
4,
19,
0,
0,
0,
0,
0,
0,
CalendarSlot::from_str("iso8601").unwrap(),
);
let positive_limit = DateTime::<()>::new(
275760,
9,
14,
0,
0,
0,
0,
0,
0,
CalendarSlot::from_str("iso8601").unwrap(),
);

assert!(negative_limit.is_err());
assert!(positive_limit.is_err());
}
}
20 changes: 12 additions & 8 deletions core/temporal/src/iso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ impl IsoDateTime {

let year = utils::epoch_time_to_epoch_year(epoch_millis);
let month = utils::epoch_time_to_month_in_year(epoch_millis) + 1;
println!("month: {month}");
let day = utils::epoch_time_to_date(epoch_millis);

// 7. Let hour be ℝ(! HourFromTime(epochMilliseconds)).
Expand Down Expand Up @@ -106,6 +107,7 @@ impl IsoDateTime {
microsecond: f64,
nanosecond: f64,
) -> Self {
println!("{month}");
let (overflow_day, time) =
IsoTime::balance(hour, minute, second, millisecond, microsecond, nanosecond);
let date = IsoDate::balance(year, month, day + overflow_day);
Expand Down Expand Up @@ -562,10 +564,10 @@ impl IsoTime {
///
/// Functionally the same as Date's `MakeTime`
pub(crate) fn to_epoch_ms(self) -> f64 {
f64::from(self.hour).mul_add(
utils::MS_PER_HOUR,
f64::from(self.minute) * utils::MS_PER_MINUTE,
) + f64::from(self.second).mul_add(1000f64, f64::from(self.millisecond))
((f64::from(self.hour) * utils::MS_PER_HOUR
+ f64::from(self.minute) * utils::MS_PER_MINUTE)
+ f64::from(self.second) * 1000f64)
+ f64::from(self.millisecond)
}
}

Expand All @@ -574,6 +576,9 @@ impl IsoTime {
#[inline]
/// Utility function to determine if a `DateTime`'s components create a `DateTime` within valid limits
fn iso_dt_within_valid_limits(date: IsoDate, time: &IsoTime) -> bool {
if iso_date_to_epoch_days(date.year, (date.month).into(), date.day.into()).abs() > 100_000_001 {
return false;
}
let Some(ns) = utc_epoch_nanos(date, time, 0.0) else {
return false;
};
Expand All @@ -587,9 +592,8 @@ fn iso_dt_within_valid_limits(date: IsoDate, time: &IsoTime) -> bool {
#[inline]
/// Utility function to convert a `IsoDate` and `IsoTime` values into epoch nanoseconds
fn utc_epoch_nanos(date: IsoDate, time: &IsoTime, offset: f64) -> Option<BigInt> {
let day = date.to_epoch_days();
let time_in_ms = time.to_epoch_ms();
let epoch_ms = utils::epoch_days_to_epoch_ms(day, time_in_ms);
let ms = time.to_epoch_ms();
let epoch_ms = utils::epoch_days_to_epoch_ms(date.to_epoch_days(), ms);

let epoch_nanos = epoch_ms.mul_add(
1_000_000f64,
Expand All @@ -614,7 +618,7 @@ fn iso_date_to_epoch_days(year: i32, month: i32, day: i32) -> i32 {
let month_t = utils::epoch_time_for_month_given_year(resolved_month, resolved_year);

// 4. Return EpochTimeToDayNumber(t) + date - 1.
utils::epoch_time_to_day_number(year_t + month_t) + day - 1
utils::epoch_time_to_day_number((year_t.abs() + month_t).copysign(year_t)) + day - 1
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion core/temporal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub type TemporalResult<T> = Result<T, TemporalError>;

// Relevant numeric constants
/// Nanoseconds per day constant: 8.64e+13
pub const NS_PER_DAY: i64 = 86_400_000_000_000;
pub const NS_PER_DAY: i64 = MS_PER_DAY as i64 * 1_000_000;
/// Milliseconds per day constant: 8.64e+7
pub const MS_PER_DAY: i32 = 24 * 60 * 60 * 1000;
/// Max Instant nanosecond constant
Expand Down
4 changes: 1 addition & 3 deletions core/temporal/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use crate::{
TemporalError, TemporalResult, MS_PER_DAY,
};

use std::ops::Mul;

// NOTE: Review the below for optimizations and add ALOT of tests.

/// Converts and validates an `Option<f64>` rounding increment value into a valid increment result.
Expand Down Expand Up @@ -264,7 +262,7 @@ pub(crate) fn epoch_time_for_month_given_year(m: i32, y: i32) -> f64 {
_ => unreachable!(),
};

f64::from(MS_PER_DAY).mul(f64::from(days))
f64::from(MS_PER_DAY) * f64::from(days)
}

pub(crate) fn epoch_time_to_date(t: f64) -> u8 {
Expand Down

0 comments on commit 9f59e52

Please sign in to comment.