diff --git a/boa_engine/src/builtins/intl/date_time_format.rs b/boa_engine/src/builtins/intl/date_time_format.rs
index b9ebee9e6e9..333c224bc41 100644
--- a/boa_engine/src/builtins/intl/date_time_format.rs
+++ b/boa_engine/src/builtins/intl/date_time_format.rs
@@ -114,3 +114,123 @@ impl DateTimeFormat {
         Ok(date_time_format.into())
     }
 }
+
+/// Represents the `required` and `defaults` arguments in the abstract operation
+/// `toDateTimeOptions`.
+///
+/// Since `required` and `defaults` differ only in the `any` and `all` variants,
+/// we combine both in a single variant `AnyAll`.
+#[allow(unused)]
+#[derive(Debug, PartialEq)]
+pub(crate) enum DateTimeReqs {
+    Date,
+    Time,
+    AnyAll,
+}
+
+/// The abstract operation `toDateTimeOptions` is called with arguments `options`, `required` and
+/// `defaults`.
+///
+/// More information:
+///  - [ECMAScript reference][spec]
+///
+/// [spec]: https://tc39.es/ecma402/#sec-todatetimeoptions
+#[allow(unused)]
+pub(crate) fn to_date_time_options(
+    options: &JsValue,
+    required: &DateTimeReqs,
+    defaults: &DateTimeReqs,
+    context: &mut Context,
+) -> JsResult<JsObject> {
+    // 1. If options is undefined, let options be null;
+    // otherwise let options be ? ToObject(options).
+    // 2. Let options be ! OrdinaryObjectCreate(options).
+    let options = if options.is_undefined() {
+        None
+    } else {
+        Some(options.to_object(context)?)
+    };
+    let options = JsObject::from_proto_and_data(options, ObjectData::ordinary());
+
+    // 3. Let needDefaults be true.
+    let mut need_defaults = true;
+
+    // 4. If required is "date" or "any", then
+    if [DateTimeReqs::Date, DateTimeReqs::AnyAll].contains(required) {
+        // a. For each property name prop of « "weekday", "year", "month", "day" », do
+        for property in ["weekday", "year", "month", "day"] {
+            // i. Let value be ? Get(options, prop).
+            let value = options.get(property, context)?;
+
+            // ii. If value is not undefined, let needDefaults be false.
+            if !value.is_undefined() {
+                need_defaults = false;
+            }
+        }
+    }
+
+    // 5. If required is "time" or "any", then
+    if [DateTimeReqs::Time, DateTimeReqs::AnyAll].contains(required) {
+        // a. For each property name prop of « "dayPeriod", "hour", "minute", "second",
+        // "fractionalSecondDigits" », do
+        for property in [
+            "dayPeriod",
+            "hour",
+            "minute",
+            "second",
+            "fractionalSecondDigits",
+        ] {
+            // i. Let value be ? Get(options, prop).
+            let value = options.get(property, context)?;
+
+            // ii. If value is not undefined, let needDefaults be false.
+            if !value.is_undefined() {
+                need_defaults = false;
+            }
+        }
+    }
+
+    // 6. Let dateStyle be ? Get(options, "dateStyle").
+    let date_style = options.get("dateStyle", context)?;
+
+    // 7. Let timeStyle be ? Get(options, "timeStyle").
+    let time_style = options.get("timeStyle", context)?;
+
+    // 8. If dateStyle is not undefined or timeStyle is not undefined, let needDefaults be false.
+    if !date_style.is_undefined() || !time_style.is_undefined() {
+        need_defaults = false;
+    }
+
+    // 9. If required is "date" and timeStyle is not undefined, then
+    if required == &DateTimeReqs::Date && !time_style.is_undefined() {
+        // a. Throw a TypeError exception.
+        return context.throw_type_error("'date' is required, but timeStyle was defined");
+    }
+
+    // 10. If required is "time" and dateStyle is not undefined, then
+    if required == &DateTimeReqs::Time && !date_style.is_undefined() {
+        // a. Throw a TypeError exception.
+        return context.throw_type_error("'time' is required, but dateStyle was defined");
+    }
+
+    // 11. If needDefaults is true and defaults is either "date" or "all", then
+    if need_defaults && [DateTimeReqs::Date, DateTimeReqs::AnyAll].contains(defaults) {
+        // a. For each property name prop of « "year", "month", "day" », do
+        for property in ["year", "month", "day"] {
+            // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
+            options.create_data_property_or_throw(property, "numeric", context)?;
+        }
+    }
+
+    // 12. If needDefaults is true and defaults is either "time" or "all", then
+    if need_defaults && [DateTimeReqs::Time, DateTimeReqs::AnyAll].contains(defaults) {
+        // a. For each property name prop of « "hour", "minute", "second" », do
+        for property in ["hour", "minute", "second"] {
+            // i. Perform ? CreateDataPropertyOrThrow(options, prop, "numeric").
+            options.create_data_property_or_throw(property, "numeric", context)?;
+        }
+    }
+
+    // 13. Return options.
+    Ok(options)
+}
diff --git a/boa_engine/src/builtins/intl/mod.rs b/boa_engine/src/builtins/intl/mod.rs
index 2c2472122cf..08c7264edcd 100644
--- a/boa_engine/src/builtins/intl/mod.rs
+++ b/boa_engine/src/builtins/intl/mod.rs
@@ -10,7 +10,7 @@
 use crate::{
     builtins::intl::date_time_format::DateTimeFormat,
     builtins::{Array, BuiltIn, JsArgs},
-    object::ObjectInitializer,
+    object::{JsObject, ObjectInitializer},
     property::Attribute,
     symbol::WellKnownSymbols,
     Context, JsResult, JsString, JsValue,
@@ -653,3 +653,115 @@ fn resolve_locale(
     // 12. Return result.
     result
 }
+
+#[allow(unused)]
+pub(crate) enum GetOptionType {
+    String,
+    Boolean,
+}
+
+/// The abstract operation `GetOption` extracts the value of the property named `property` from the
+/// provided `options` object, converts it to the required `type`, checks whether it is one of a
+/// `List` of allowed `values`, and fills in a `fallback` value if necessary. If `values` is
+/// undefined, there is no fixed set of values and any is permitted.
+///
+/// More information:
+///  - [ECMAScript reference][spec]
+///
+/// [spec]: https://tc39.es/ecma402/#sec-getoption
+#[allow(unused)]
+pub(crate) fn get_option(
+    options: &JsObject,
+    property: &str,
+    r#type: &GetOptionType,
+    values: &[JsString],
+    fallback: &JsValue,
+    context: &mut Context,
+) -> JsResult<JsValue> {
+    // 1. Assert: Type(options) is Object.
+    // 2. Let value be ? Get(options, property).
+    let mut value = options.get(property, context)?;
+
+    // 3. If value is undefined, return fallback.
+    if value.is_undefined() {
+        return Ok(fallback.clone());
+    }
+
+    // 4. Assert: type is "boolean" or "string".
+    // 5. If type is "boolean", then
+    //      a. Set value to ! ToBoolean(value).
+    // 6. If type is "string", then
+    //      a. Set value to ? ToString(value).
+    // 7. If values is not undefined and values does not contain an element equal to value,
+    // throw a RangeError exception.
+    value = match r#type {
+        GetOptionType::Boolean => JsValue::Boolean(value.to_boolean()),
+        GetOptionType::String => {
+            let string_value = value.to_string(context)?;
+            if !values.is_empty() && !values.contains(&string_value) {
+                return context.throw_range_error("GetOption: values array does not contain value");
+            }
+            JsValue::String(string_value)
+        }
+    };
+
+    // 8. Return value.
+    Ok(value)
+}
+
+/// The abstract operation `GetNumberOption` extracts the value of the property named `property`
+/// from the provided `options` object, converts it to a `Number value`, checks whether it is in
+/// the allowed range, and fills in a `fallback` value if necessary.
+///
+/// More information:
+///  - [ECMAScript reference][spec]
+///
+/// [spec]: https://tc39.es/ecma402/#sec-getnumberoption
+#[allow(unused)]
+pub(crate) fn get_number_option(
+    options: &JsObject,
+    property: &str,
+    minimum: f64,
+    maximum: f64,
+    fallback: Option<f64>,
+    context: &mut Context,
+) -> JsResult<Option<f64>> {
+    // 1. Assert: Type(options) is Object.
+    // 2. Let value be ? Get(options, property).
+    let value = options.get(property, context)?;
+
+    // 3. Return ? DefaultNumberOption(value, minimum, maximum, fallback).
+    default_number_option(&value, minimum, maximum, fallback, context)
+}
+
+/// The abstract operation `DefaultNumberOption` converts `value` to a `Number value`, checks
+/// whether it is in the allowed range, and fills in a `fallback` value if necessary.
+///
+/// More information:
+///  - [ECMAScript reference][spec]
+///
+/// [spec]: https://tc39.es/ecma402/#sec-defaultnumberoption
+#[allow(unused)]
+pub(crate) fn default_number_option(
+    value: &JsValue,
+    minimum: f64,
+    maximum: f64,
+    fallback: Option<f64>,
+    context: &mut Context,
+) -> JsResult<Option<f64>> {
+    // 1. If value is undefined, return fallback.
+    if value.is_undefined() {
+        return Ok(fallback);
+    }
+
+    // 2. Set value to ? ToNumber(value).
+    let value = value.to_number(context)?;
+
+    // 3. If value is NaN or less than minimum or greater than maximum, throw a RangeError exception.
+    if value.is_nan() || value < minimum || value > maximum {
+        return context.throw_range_error("DefaultNumberOption: value is out of range.");
+    }
+
+    // 4. Return floor(value).
+    Ok(Some(value.floor()))
+}
diff --git a/boa_engine/src/builtins/intl/tests.rs b/boa_engine/src/builtins/intl/tests.rs
index b0a3d8de36e..7a125b108a7 100644
--- a/boa_engine/src/builtins/intl/tests.rs
+++ b/boa_engine/src/builtins/intl/tests.rs
@@ -1,4 +1,13 @@
-use crate::{Context, JsString};
+use crate::{
+    builtins::intl::date_time_format::{to_date_time_options, DateTimeReqs},
+    builtins::intl::{
+        best_available_locale, best_fit_matcher, default_locale, default_number_option,
+        get_number_option, get_option, insert_unicode_extension_and_canonicalize, lookup_matcher,
+        resolve_locale, unicode_extension_components, DateTimeFormatRecord, GetOptionType,
+    },
+    object::JsObject,
+    Context, JsString, JsValue,
+};
 
 use rustc_hash::FxHashMap;
 
@@ -7,14 +16,14 @@ fn best_avail_loc() {
     let no_extensions_locale = JsString::new("en-US");
     let available_locales = Vec::<JsString>::new();
     assert_eq!(
-        crate::builtins::intl::best_available_locale(&available_locales, &no_extensions_locale,),
+        best_available_locale(&available_locales, &no_extensions_locale,),
         None
     );
 
     let no_extensions_locale = JsString::new("de-DE");
     let available_locales = vec![no_extensions_locale.clone()];
     assert_eq!(
-        crate::builtins::intl::best_available_locale(&available_locales, &no_extensions_locale,),
+        best_available_locale(&available_locales, &no_extensions_locale,),
         Some(no_extensions_locale)
     );
 
@@ -22,7 +31,7 @@ fn best_avail_loc() {
     let no_extensions_locale = JsString::new(locale_part.clone() + &"-CA".to_string());
     let available_locales = vec![JsString::new(locale_part.clone())];
     assert_eq!(
-        crate::builtins::intl::best_available_locale(&available_locales, &no_extensions_locale,),
+        best_available_locale(&available_locales, &no_extensions_locale,),
         Some(JsString::new(locale_part))
     );
 
@@ -31,7 +40,7 @@ fn best_avail_loc() {
     let no_extensions_locale = JsString::new("ja-Kana-JP-t-it-latn-it");
     let available_locales = vec![ja_kana_t.clone(), ja_kana.clone()];
     assert_eq!(
-        crate::builtins::intl::best_available_locale(&available_locales, &no_extensions_locale,),
+        best_available_locale(&available_locales, &no_extensions_locale,),
         Some(ja_kana)
     );
 }
@@ -42,23 +51,23 @@ fn lookup_match() {
     let available_locales = Vec::<JsString>::new();
     let requested_locales = Vec::<JsString>::new();
 
-    let matcher = crate::builtins::intl::lookup_matcher(&available_locales, &requested_locales);
-    assert_eq!(matcher.locale, crate::builtins::intl::default_locale());
+    let matcher = lookup_matcher(&available_locales, &requested_locales);
+    assert_eq!(matcher.locale, default_locale());
     assert_eq!(matcher.extension, "");
 
     // available: [de-DE], requested: []
     let available_locales = vec![JsString::new("de-DE")];
     let requested_locales = Vec::<JsString>::new();
 
-    let matcher = crate::builtins::intl::lookup_matcher(&available_locales, &requested_locales);
-    assert_eq!(matcher.locale, crate::builtins::intl::default_locale());
+    let matcher = lookup_matcher(&available_locales, &requested_locales);
+    assert_eq!(matcher.locale, default_locale());
     assert_eq!(matcher.extension, "");
 
     // available: [fr-FR], requested: [fr-FR-u-hc-h12]
     let available_locales = vec![JsString::new("fr-FR")];
     let requested_locales = vec![JsString::new("fr-FR-u-hc-h12")];
 
-    let matcher = crate::builtins::intl::lookup_matcher(&available_locales, &requested_locales);
+    let matcher = lookup_matcher(&available_locales, &requested_locales);
     assert_eq!(matcher.locale, "fr-FR");
     assert_eq!(matcher.extension, "-u-hc-h12");
 
@@ -66,7 +75,7 @@ fn lookup_match() {
     let available_locales = vec![JsString::new("es-ES")];
     let requested_locales = vec![JsString::new("es-ES")];
 
-    let matcher = crate::builtins::intl::best_fit_matcher(&available_locales, &requested_locales);
+    let matcher = best_fit_matcher(&available_locales, &requested_locales);
     assert_eq!(matcher.locale, "es-ES");
     assert_eq!(matcher.extension, "");
 }
@@ -76,21 +85,21 @@ fn insert_unicode_ext() {
     let locale = JsString::new("hu-HU");
     let ext = JsString::empty();
     assert_eq!(
-        crate::builtins::intl::insert_unicode_extension_and_canonicalize(&locale, &ext),
+        insert_unicode_extension_and_canonicalize(&locale, &ext),
         locale
     );
 
     let locale = JsString::new("hu-HU");
     let ext = JsString::new("-u-hc-h12");
     assert_eq!(
-        crate::builtins::intl::insert_unicode_extension_and_canonicalize(&locale, &ext),
+        insert_unicode_extension_and_canonicalize(&locale, &ext),
         JsString::new("hu-HU-u-hc-h12")
     );
 
     let locale = JsString::new("hu-HU-x-PRIVATE");
     let ext = JsString::new("-u-hc-h12");
     assert_eq!(
-        crate::builtins::intl::insert_unicode_extension_and_canonicalize(&locale, &ext),
+        insert_unicode_extension_and_canonicalize(&locale, &ext),
         JsString::new("hu-HU-u-hc-h12-x-PRIVATE")
     );
 }
@@ -98,7 +107,7 @@ fn insert_unicode_ext() {
 #[test]
 fn uni_ext_comp() {
     let ext = JsString::new("-u-ca-japanese-hc-h12");
-    let components = crate::builtins::intl::unicode_extension_components(&ext);
+    let components = unicode_extension_components(&ext);
     assert_eq!(components.attributes.is_empty(), true);
     assert_eq!(components.keywords.len(), 2);
     assert_eq!(components.keywords[0].key, "ca");
@@ -107,7 +116,7 @@ fn uni_ext_comp() {
     assert_eq!(components.keywords[1].value, "h12");
 
     let ext = JsString::new("-u-alias-co-phonebk-ka-shifted");
-    let components = crate::builtins::intl::unicode_extension_components(&ext);
+    let components = unicode_extension_components(&ext);
     assert_eq!(components.attributes, vec![JsString::new("alias")]);
     assert_eq!(components.keywords.len(), 2);
     assert_eq!(components.keywords[0].key, "co");
@@ -116,7 +125,7 @@ fn uni_ext_comp() {
     assert_eq!(components.keywords[1].value, "shifted");
 
     let ext = JsString::new("-u-ca-buddhist-kk-nu-thai");
-    let components = crate::builtins::intl::unicode_extension_components(&ext);
+    let components = unicode_extension_components(&ext);
     assert_eq!(components.attributes.is_empty(), true);
     assert_eq!(components.keywords.len(), 3);
     assert_eq!(components.keywords[0].key, "ca");
@@ -127,7 +136,7 @@ fn uni_ext_comp() {
     assert_eq!(components.keywords[2].value, "thai");
 
     let ext = JsString::new("-u-ca-islamic-civil");
-    let components = crate::builtins::intl::unicode_extension_components(&ext);
+    let components = unicode_extension_components(&ext);
     assert_eq!(components.attributes.is_empty(), true);
     assert_eq!(components.keywords.len(), 1);
     assert_eq!(components.keywords[0].key, "ca");
@@ -143,12 +152,12 @@ fn locale_resolution() {
     let requested_locales = Vec::<JsString>::new();
     let relevant_extension_keys = Vec::<JsString>::new();
     let locale_data = FxHashMap::default();
-    let options = crate::builtins::intl::DateTimeFormatRecord {
+    let options = DateTimeFormatRecord {
         locale_matcher: JsString::new("lookup"),
         properties: FxHashMap::default(),
     };
 
-    let locale_record = crate::builtins::intl::resolve_locale(
+    let locale_record = resolve_locale(
         &available_locales,
         &requested_locales,
         &options,
@@ -156,14 +165,8 @@ fn locale_resolution() {
         &locale_data,
         &mut context,
     );
-    assert_eq!(
-        locale_record.locale,
-        crate::builtins::intl::default_locale()
-    );
-    assert_eq!(
-        locale_record.data_locale,
-        crate::builtins::intl::default_locale()
-    );
+    assert_eq!(locale_record.locale, default_locale());
+    assert_eq!(locale_record.data_locale, default_locale());
     assert_eq!(locale_record.properties.is_empty(), true);
 
     // test best fit
@@ -171,12 +174,12 @@ fn locale_resolution() {
     let requested_locales = Vec::<JsString>::new();
     let relevant_extension_keys = Vec::<JsString>::new();
     let locale_data = FxHashMap::default();
-    let options = crate::builtins::intl::DateTimeFormatRecord {
+    let options = DateTimeFormatRecord {
         locale_matcher: JsString::new("best-fit"),
         properties: FxHashMap::default(),
     };
 
-    let locale_record = crate::builtins::intl::resolve_locale(
+    let locale_record = resolve_locale(
         &available_locales,
         &requested_locales,
         &options,
@@ -184,14 +187,8 @@ fn locale_resolution() {
         &locale_data,
         &mut context,
     );
-    assert_eq!(
-        locale_record.locale,
-        crate::builtins::intl::default_locale()
-    );
-    assert_eq!(
-        locale_record.data_locale,
-        crate::builtins::intl::default_locale()
-    );
+    assert_eq!(locale_record.locale, default_locale());
+    assert_eq!(locale_record.data_locale, default_locale());
     assert_eq!(locale_record.properties.is_empty(), true);
 
     // available: [es-ES], requested: [es-ES]
@@ -199,12 +196,12 @@ fn locale_resolution() {
     let requested_locales = vec![JsString::new("es-ES")];
     let relevant_extension_keys = Vec::<JsString>::new();
     let locale_data = FxHashMap::default();
-    let options = crate::builtins::intl::DateTimeFormatRecord {
+    let options = DateTimeFormatRecord {
         locale_matcher: JsString::new("lookup"),
         properties: FxHashMap::default(),
     };
 
-    let locale_record = crate::builtins::intl::resolve_locale(
+    let locale_record = resolve_locale(
         &available_locales,
         &requested_locales,
         &options,
@@ -221,12 +218,12 @@ fn locale_resolution() {
     let requested_locales = Vec::<JsString>::new();
     let relevant_extension_keys = Vec::<JsString>::new();
     let locale_data = FxHashMap::default();
-    let options = crate::builtins::intl::DateTimeFormatRecord {
+    let options = DateTimeFormatRecord {
         locale_matcher: JsString::new("lookup"),
         properties: FxHashMap::default(),
     };
 
-    let locale_record = crate::builtins::intl::resolve_locale(
+    let locale_record = resolve_locale(
         &available_locales,
         &requested_locales,
         &options,
@@ -234,13 +231,284 @@ fn locale_resolution() {
         &locale_data,
         &mut context,
     );
+    assert_eq!(locale_record.locale, default_locale());
+    assert_eq!(locale_record.data_locale, default_locale());
+    assert_eq!(locale_record.properties.is_empty(), true);
+}
+
+#[test]
+fn get_opt() {
+    let mut context = Context::default();
+
+    let values = Vec::<JsString>::new();
+    let fallback = JsValue::String(JsString::new("fallback"));
+    let options_obj = JsObject::empty();
+    let option_type = GetOptionType::String;
+    let get_option_result = get_option(
+        &options_obj,
+        "",
+        &option_type,
+        &values,
+        &fallback,
+        &mut context,
+    )
+    .expect("GetOption should not fail on fallback test");
+    assert_eq!(get_option_result, fallback);
+
+    let values = Vec::<JsString>::new();
+    let fallback = JsValue::String(JsString::new("fallback"));
+    let options_obj = JsObject::empty();
+    let locale_value = JsValue::String(JsString::new("en-US"));
+    options_obj
+        .set("Locale", locale_value.clone(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let option_type = GetOptionType::String;
+    let get_option_result = get_option(
+        &options_obj,
+        "Locale",
+        &option_type,
+        &values,
+        &fallback,
+        &mut context,
+    )
+    .expect("GetOption should not fail on string test");
+    assert_eq!(get_option_result, locale_value);
+
+    let fallback = JsValue::String(JsString::new("fallback"));
+    let options_obj = JsObject::empty();
+    let locale_string = JsString::new("en-US");
+    let locale_value = JsValue::String(locale_string.clone());
+    let values = vec![locale_string];
+    options_obj
+        .set("Locale", locale_value.clone(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let option_type = GetOptionType::String;
+    let get_option_result = get_option(
+        &options_obj,
+        "Locale",
+        &option_type,
+        &values,
+        &fallback,
+        &mut context,
+    )
+    .expect("GetOption should not fail on values test");
+    assert_eq!(get_option_result, locale_value);
+
+    let fallback = JsValue::new(false);
+    let options_obj = JsObject::empty();
+    let boolean_value = JsValue::new(true);
+    let values = Vec::<JsString>::new();
+    options_obj
+        .set("boolean_val", boolean_value.clone(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let option_type = GetOptionType::Boolean;
+    let get_option_result = get_option(
+        &options_obj,
+        "boolean_val",
+        &option_type,
+        &values,
+        &fallback,
+        &mut context,
+    )
+    .expect("GetOption should not fail on boolean test");
+    assert_eq!(get_option_result, boolean_value);
+
+    let fallback = JsValue::String(JsString::new("fallback"));
+    let options_obj = JsObject::empty();
+    let locale_value = JsValue::String(JsString::new("en-US"));
+    let other_locale_str = JsString::new("de-DE");
+    let values = vec![other_locale_str];
+    options_obj
+        .set("Locale", locale_value.clone(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let option_type = GetOptionType::String;
+    let get_option_result = get_option(
+        &options_obj,
+        "Locale",
+        &option_type,
+        &values,
+        &fallback,
+        &mut context,
+    );
+    assert_eq!(get_option_result.is_err(), true);
+
+    let value = JsValue::undefined();
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback_val = 5.0;
+    let fallback = Some(fallback_val);
+    let get_option_result = default_number_option(&value, minimum, maximum, fallback, &mut context);
+    assert_eq!(get_option_result, Ok(fallback));
+
+    let value = JsValue::nan();
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback = Some(5.0);
+    let get_option_result = default_number_option(&value, minimum, maximum, fallback, &mut context);
+    assert_eq!(get_option_result.is_err(), true);
+
+    let value = JsValue::new(0);
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback = Some(5.0);
+    let get_option_result = default_number_option(&value, minimum, maximum, fallback, &mut context);
+    assert_eq!(get_option_result.is_err(), true);
+
+    let value = JsValue::new(11);
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback = Some(5.0);
+    let get_option_result = default_number_option(&value, minimum, maximum, fallback, &mut context);
+    assert_eq!(get_option_result.is_err(), true);
+
+    let value_f64 = 7.0;
+    let value = JsValue::new(value_f64);
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback = Some(5.0);
+    let get_option_result = default_number_option(&value, minimum, maximum, fallback, &mut context);
+    assert_eq!(get_option_result, Ok(Some(value_f64)));
+
+    let options = JsObject::empty();
+    let property = "fractionalSecondDigits";
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback_val = 5.0;
+    let fallback = Some(fallback_val);
+    let get_option_result = get_number_option(
+        &options,
+        &property,
+        minimum,
+        maximum,
+        fallback,
+        &mut context,
+    );
+    assert_eq!(get_option_result, Ok(fallback));
+
+    let options = JsObject::empty();
+    let value_f64 = 8.0;
+    let value = JsValue::new(value_f64);
+    let property = "fractionalSecondDigits";
+    options
+        .set(property, value.clone(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let minimum = 1.0;
+    let maximum = 10.0;
+    let fallback = Some(5.0);
+    let get_option_result = get_number_option(
+        &options,
+        &property,
+        minimum,
+        maximum,
+        fallback,
+        &mut context,
+    );
+    assert_eq!(get_option_result, Ok(Some(value_f64)));
+}
+
+#[test]
+fn to_date_time_opts() {
+    let mut context = Context::default();
+
+    let options_obj = JsObject::empty();
+    options_obj
+        .set("timeStyle", JsObject::empty(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let date_time_opts = to_date_time_options(
+        &JsValue::new(options_obj),
+        &DateTimeReqs::Date,
+        &DateTimeReqs::Date,
+        &mut context,
+    );
+    assert_eq!(date_time_opts.is_err(), true);
+
+    let options_obj = JsObject::empty();
+    options_obj
+        .set("dateStyle", JsObject::empty(), true, &mut context)
+        .expect("Setting a property should not fail");
+    let date_time_opts = to_date_time_options(
+        &JsValue::new(options_obj),
+        &DateTimeReqs::Time,
+        &DateTimeReqs::Time,
+        &mut context,
+    );
+    assert_eq!(date_time_opts.is_err(), true);
+
+    let date_time_opts = to_date_time_options(
+        &JsValue::undefined(),
+        &DateTimeReqs::Date,
+        &DateTimeReqs::Date,
+        &mut context,
+    )
+    .expect("toDateTimeOptions should not fail in date test");
+
+    let numeric_jsstring = JsValue::String(JsString::new("numeric"));
     assert_eq!(
-        locale_record.locale,
-        crate::builtins::intl::default_locale()
+        date_time_opts.get("year", &mut context),
+        Ok(numeric_jsstring.clone())
     );
     assert_eq!(
-        locale_record.data_locale,
-        crate::builtins::intl::default_locale()
+        date_time_opts.get("month", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("day", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+
+    let date_time_opts = to_date_time_options(
+        &JsValue::undefined(),
+        &DateTimeReqs::Time,
+        &DateTimeReqs::Time,
+        &mut context,
+    )
+    .expect("toDateTimeOptions should not fail in time test");
+
+    let numeric_jsstring = JsValue::String(JsString::new("numeric"));
+    assert_eq!(
+        date_time_opts.get("hour", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("minute", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("second", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+
+    let date_time_opts = to_date_time_options(
+        &JsValue::undefined(),
+        &DateTimeReqs::AnyAll,
+        &DateTimeReqs::AnyAll,
+        &mut context,
+    )
+    .expect("toDateTimeOptions should not fail when testing required = 'any'");
+
+    let numeric_jsstring = JsValue::String(JsString::new("numeric"));
+    assert_eq!(
+        date_time_opts.get("year", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("month", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("day", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("hour", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("minute", &mut context),
+        Ok(numeric_jsstring.clone())
+    );
+    assert_eq!(
+        date_time_opts.get("second", &mut context),
+        Ok(numeric_jsstring.clone())
     );
-    assert_eq!(locale_record.properties.is_empty(), true);
 }