Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ intrusive-collections = "0.9.7"
cfg-if = "1.0.0"
either = "1.15.0"
sys-locale = "0.3.2"
temporal_rs = { git = "https://github.com/boa-dev/temporal.git", rev = "ca7a601580cbb240c751bfc0de000a1a48e9766d", default-features = false, features = [
temporal_rs = { git = "https://github.com/boa-dev/temporal.git", rev = "6e7e341e15625cbc85a8842b794224c16da58fb6", default-features = false, features = [
"tzdb",
] }
web-time = "1.1.0"
Expand Down
94 changes: 42 additions & 52 deletions core/engine/src/builtins/temporal/duration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,29 +292,29 @@ impl BuiltInConstructor for Duration {
let microseconds = args.get_or_undefined(8).map_or(Ok(0), |v| {
let finite = v.to_finitef64(context)?;
finite
.as_integer_if_integral::<i64>()
.as_integer_if_integral::<i128>()
.map_err(JsError::from)
})?;

// 11. If nanoseconds is undefined, let ns be 0; else let ns be ? ToIntegerIfIntegral(nanoseconds).
let nanoseconds = args.get_or_undefined(9).map_or(Ok(0), |v| {
let finite = v.to_finitef64(context)?;
finite
.as_integer_if_integral::<i64>()
.as_integer_if_integral::<i128>()
.map_err(JsError::from)
})?;

let record = InnerDuration::new(
years.try_into()?,
months.try_into()?,
weeks.try_into()?,
days.try_into()?,
hours.try_into()?,
minutes.try_into()?,
seconds.try_into()?,
milliseconds.try_into()?,
microseconds.try_into()?,
nanoseconds.try_into()?,
years,
months,
weeks,
days,
hours,
minutes,
seconds,
milliseconds,
microseconds,
nanoseconds,
)?;

// 12. Return ? CreateTemporalDuration(y, mo, w, d, h, m, s, ms, mis, ns, NewTarget).
Expand All @@ -337,16 +337,16 @@ impl Duration {
let inner = &duration.inner;

match field {
DateTimeValues::Year => Ok(JsValue::new(inner.years().as_inner())),
DateTimeValues::Month => Ok(JsValue::new(inner.months().as_inner())),
DateTimeValues::Week => Ok(JsValue::new(inner.weeks().as_inner())),
DateTimeValues::Day => Ok(JsValue::new(inner.days().as_inner())),
DateTimeValues::Hour => Ok(JsValue::new(inner.hours().as_inner())),
DateTimeValues::Minute => Ok(JsValue::new(inner.minutes().as_inner())),
DateTimeValues::Second => Ok(JsValue::new(inner.seconds().as_inner())),
DateTimeValues::Millisecond => Ok(JsValue::new(inner.milliseconds().as_inner())),
DateTimeValues::Microsecond => Ok(JsValue::new(inner.microseconds().as_inner())),
DateTimeValues::Nanosecond => Ok(JsValue::new(inner.nanoseconds().as_inner())),
DateTimeValues::Year => Ok(JsValue::new(inner.years())),
DateTimeValues::Month => Ok(JsValue::new(inner.months())),
DateTimeValues::Week => Ok(JsValue::new(inner.weeks())),
DateTimeValues::Day => Ok(JsValue::new(inner.days())),
DateTimeValues::Hour => Ok(JsValue::new(inner.hours())),
DateTimeValues::Minute => Ok(JsValue::new(inner.minutes())),
DateTimeValues::Second => Ok(JsValue::new(inner.seconds())),
DateTimeValues::Millisecond => Ok(JsValue::new(inner.milliseconds())),
DateTimeValues::Microsecond => Ok(JsValue::new(inner.microseconds() as f64)),
DateTimeValues::Nanosecond => Ok(JsValue::new(inner.nanoseconds() as f64)),
DateTimeValues::MonthCode => unreachable!(
"Any other DateTimeValue fields on Duration would be an implementation error."
),
Expand Down Expand Up @@ -1030,10 +1030,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("days"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1043,10 +1042,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("hours"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1056,10 +1054,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("microseconds"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i128>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1069,10 +1066,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("milliseconds"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1082,10 +1078,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("minutes"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1095,10 +1090,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("months"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1108,10 +1102,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("nanoseconds"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i128>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1121,10 +1114,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("seconds"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1134,10 +1126,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("weeks"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand All @@ -1147,10 +1138,9 @@ pub(crate) fn to_temporal_partial_duration(
.get(js_string!("years"), context)?
.map(|v| {
let finite = v.to_finitef64(context)?;
let integral_int = finite
finite
.as_integer_if_integral::<i64>()
.map_err(JsError::from)?;
integral_int.try_into().map_err(JsError::from)
.map_err(JsError::from)
})
.transpose()?;

Expand Down
2 changes: 1 addition & 1 deletion core/engine/src/builtins/temporal/plain_date_time/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl IntrinsicObject for PlainDateTime {
.static_method(Self::from, js_string!("from"), 1)
.static_method(Self::compare, js_string!("compare"), 2)
.method(Self::with, js_string!("with"), 1)
.method(Self::with_plain_time, js_string!("withPlainTime"), 1)
.method(Self::with_plain_time, js_string!("withPlainTime"), 0)
.method(Self::with_calendar, js_string!("withCalendar"), 1)
.method(Self::add, js_string!("add"), 1)
.method(Self::subtract, js_string!("subtract"), 1)
Expand Down
89 changes: 74 additions & 15 deletions core/engine/src/builtins/temporal/zoneddatetime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use cow_utils::CowUtils;
use temporal_rs::{
options::{
ArithmeticOverflow, Disambiguation, DisplayCalendar, DisplayOffset, DisplayTimeZone,
OffsetDisambiguation, RoundingMode, ToStringRoundingOptions, Unit,
OffsetDisambiguation, RoundingIncrement, RoundingMode, RoundingOptions,
ToStringRoundingOptions, Unit,
},
partial::{PartialDate, PartialTime, PartialZonedDateTime},
provider::{TimeZoneProvider, TransitionDirection},
Expand All @@ -33,7 +34,7 @@ use super::{
calendar::{get_temporal_calendar_slot_value_with_default, to_temporal_calendar_slot_value},
create_temporal_date, create_temporal_datetime, create_temporal_duration,
create_temporal_instant, create_temporal_time, is_partial_temporal_object,
options::get_difference_settings,
options::{get_difference_settings, get_temporal_unit, TemporalUnitGroup},
to_temporal_duration, to_temporal_time,
};

Expand Down Expand Up @@ -903,18 +904,22 @@ impl ZonedDateTime {
// 19. Let resolvedOptions be ? GetOptionsObject(options).
let resolved_options = get_options_object(args.get_or_undefined(1))?;
// 20. Let disambiguation be ? GetTemporalDisambiguationOption(resolvedOptions).
let _disambiguation =
get_option::<Disambiguation>(&resolved_options, js_string!("disambiguation"), context)?
.unwrap_or_default();
let disambiguation =
get_option::<Disambiguation>(&resolved_options, js_string!("disambiguation"), context)?;
// 21. Let offset be ? GetTemporalOffsetOption(resolvedOptions, prefer).
let _offset =
get_option::<OffsetDisambiguation>(&resolved_options, js_string!("offset"), context)?
.unwrap_or(OffsetDisambiguation::Prefer);
let offset =
get_option::<OffsetDisambiguation>(&resolved_options, js_string!("offset"), context)?;
// 22. Let overflow be ? GetTemporalOverflowOption(resolvedOptions).
let _overflow =
let overflow =
get_option::<ArithmeticOverflow>(&resolved_options, js_string!("overflow"), context)?;

let result = zdt.inner.with(partial)?;
let result = zdt.inner.with(
partial,
disambiguation,
offset,
overflow,
context.tz_provider(),
)?;
create_temporal_zoneddatetime(result, None, context).map(Into::into)
}

Expand Down Expand Up @@ -1055,17 +1060,71 @@ impl ZonedDateTime {
}

/// 6.3.39 `Temporal.ZonedDateTime.prototype.round ( roundTo )`
fn round(this: &JsValue, _args: &[JsValue], _context: &mut Context) -> JsResult<JsValue> {
let _zdt = this
fn round(this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
// 1. Let zonedDateTime be the this value.
// 2. Perform ? RequireInternalSlot(zonedDateTime, [[InitializedTemporalZonedDateTime]]).
let zdt = this
.as_object()
.and_then(JsObject::downcast_ref::<Self>)
.ok_or_else(|| {
JsNativeError::typ().with_message("the this object must be a ZonedDateTime object.")
})?;

Err(JsNativeError::error()
.with_message("Not yet implemented.")
.into())
let round_to = match args.first().map(JsValue::variant) {
// 3. If roundTo is undefined, then
None | Some(JsVariant::Undefined) => {
// a. Throw a TypeError exception.
return Err(JsNativeError::typ()
.with_message("roundTo cannot be undefined.")
.into());
}
// 4. If Type(roundTo) is String, then
Some(JsVariant::String(rt)) => {
// a. Let paramString be roundTo.
let param_string = rt.clone();
// b. Set roundTo to OrdinaryObjectCreate(null).
let new_round_to = JsObject::with_null_proto();
// c. Perform ! CreateDataPropertyOrThrow(roundTo, "smallestUnit", paramString).
new_round_to.create_data_property_or_throw(
js_string!("smallestUnit"),
param_string,
context,
)?;
new_round_to
}
// 5. Else,
Some(round_to) => {
// a. Set roundTo to ? GetOptionsObject(roundTo).
get_options_object(&JsValue::from(round_to))?
}
};

// 6. NOTE: The following steps read options and perform independent validation
// in alphabetical order (GetRoundingIncrementOption reads "roundingIncrement"
// and GetRoundingModeOption reads "roundingMode").
let mut options = RoundingOptions::default();

// 7. Let roundingIncrement be ? GetRoundingIncrementOption(roundTo).
options.increment =
get_option::<RoundingIncrement>(&round_to, js_string!("roundingIncrement"), context)?;

// 8. Let roundingMode be ? GetRoundingModeOption(roundTo, half-expand).
options.rounding_mode =
get_option::<RoundingMode>(&round_to, js_string!("roundingMode"), context)?;

// 9. Let smallestUnit be ? GetTemporalUnitValuedOption(roundTo, "smallestUnit", time, required, « day »).
options.smallest_unit = get_temporal_unit(
&round_to,
js_string!("smallestUnit"),
TemporalUnitGroup::Time,
Some(vec![Unit::Day]),
context,
)?;

let result = zdt
.inner
.round_with_provider(options, context.tz_provider())?;
create_temporal_zoneddatetime(result, None, context).map(Into::into)
}

/// 6.3.40 `Temporal.ZonedDateTime.prototype.equals ( other )`
Expand Down
Loading