Skip to content
Open
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
33 changes: 10 additions & 23 deletions core/engine/src/builtins/intl/date_time_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,18 @@ impl BuiltInConstructor for DateTimeFormat {
let options = args.get_or_undefined(1);

// 2. Let dateTimeFormat be ? CreateDateTimeFormat(newTarget, locales, options, any, date).
let prototype = get_prototype_from_constructor(
new_target_inner,
StandardConstructors::date_time_format,
context,
)?;
let dtf = create_date_time_format(
locales,
options,
FormatType::Any,
FormatDefaults::Date,
context,
)?;
let prototype = get_prototype_from_constructor(
new_target_inner,
StandardConstructors::date_time_format,
context,
)?;
let date_time_format = JsObject::from_proto_and_data(prototype, dtf);

// 3. If the implementation supports the normative optional constructor mode of 4.3 Note 1, then
Expand Down Expand Up @@ -534,6 +534,11 @@ pub(crate) fn create_date_time_format(
defaults: FormatDefaults,
context: &mut Context,
) -> JsResult<DateTimeFormat> {
// NOTE: The below step's code was moved out into constructor to prevent unnecessary JsObject allocation when we create dtf internally
// (e.g. toLocaleString methods of Date and Temporal objects)
// 1. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%Intl.DateTimeFormat.prototype%",
// « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]],
// [[HourCycle]], [[DateStyle]], [[TimeStyle]], [[DateTimeFormat]], [[BoundFormat]] »).
// 2. Let hour12 be undefined. <- TODO
// 3. Let modifyResolutionOptions be a new Abstract Closure with parameters (options) that captures hour12 and performs the following steps when called:
// a. Set hour12 to options.[[hour12]].
Expand Down Expand Up @@ -1025,24 +1030,6 @@ pub(crate) fn format_date_time_locale(
context: &mut Context,
) -> JsResult<JsValue> {
let options = coerce_options_to_object(options, context)?;
if format_type != FormatType::Time
&& get_option::<DateStyle>(&options, js_string!("dateStyle"), context)?.is_none()
{
options.create_data_property_or_throw(
js_string!("dateStyle"),
JsValue::from(js_string!("long")),
context,
)?;
}
if format_type != FormatType::Date
&& get_option::<TimeStyle>(&options, js_string!("timeStyle"), context)?.is_none()
{
options.create_data_property_or_throw(
js_string!("timeStyle"),
JsValue::from(js_string!("long")),
context,
)?;
}
let options_value = options.into();
let dtf = create_date_time_format(locales, &options_value, format_type, defaults, context)?;
// FormatDateTime steps 1–2: TimeClip and NaN check (format_timestamp_with_dtf does ToLocalTime + format only).
Expand Down
51 changes: 51 additions & 0 deletions core/engine/src/builtins/intl/date_time_format/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,54 @@ fn dtf_basic() {
TestAction::assert_eq("result === 'Sunday, 20 December 2020 at 14:23:16'", true),
]);
}

#[cfg(feature = "intl_bundled")]
#[test]
fn date_to_locale_string() {
run_test_actions([
TestAction::run(indoc! {"
// Setup date
const date = new Date(Date.UTC(2021, 3, 12, 6, 7));

let result = date.toLocaleString('en-US', { dateStyle: 'short' });
"}),
TestAction::assert_eq("result === '4/12/21'", true),
]);
run_test_actions([
TestAction::run(indoc! {"
// Setup date
const date = new Date(Date.UTC(2021, 3, 12, 6, 7));

let result = date.toLocaleString('en-US', { timeStyle: 'short' });
"}),
TestAction::assert_eq("result === '6:07\u{202f}AM'", true),
]);
}

#[cfg(feature = "intl_bundled")]
#[test]
fn dtf_ctor_observable_behavior() {
run_test_actions([
TestAction::run(indoc! {"
const expected = [];

const proxyConstructor = new Proxy(Intl.DateTimeFormat, {
get(target, prop) {
if (prop === 'prototype') {
expected.push('prototype-access');
}
return target[prop];
}
});

try {
new proxyConstructor('en', { timeZone: 'Invalid/Zone' });
} catch (e) {
expected.push('error-thrown');
}
"}),
TestAction::assert_eq("expected.length === 2", true),
TestAction::assert_eq("expected[0] === 'prototype-access'", true),
TestAction::assert_eq("expected[1] === 'error-thrown'", true),
]);
}
Loading