From f4c6508e6034cc22580636a256c192a8a37043d5 Mon Sep 17 00:00:00 2001 From: anuvratsingh Date: Sun, 17 Jul 2022 20:34:41 +0530 Subject: [PATCH] Fix: `get_*` and other `&self` using internal methods` --- boa_engine/src/builtins/date/mod.rs | 502 ++++++++++++++++++++-------- boa_engine/src/object/jsdate.rs | 444 ++++++++++++------------ 2 files changed, 609 insertions(+), 337 deletions(-) diff --git a/boa_engine/src/builtins/date/mod.rs b/boa_engine/src/builtins/date/mod.rs index 9ab48810bcc..78faf69aa70 100644 --- a/boa_engine/src/builtins/date/mod.rs +++ b/boa_engine/src/builtins/date/mod.rs @@ -46,21 +46,6 @@ fn ignore_ambiguity(result: LocalResult) -> Option { } } -macro_rules! getter_method { - ($name:ident) => {{ - fn get_value(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult { - Ok(JsValue::new(this_time_value(this, context)?.$name())) - } - get_value - }}; - (Self::$name:ident) => {{ - fn get_value(_: &JsValue, _: &[JsValue], _: &mut Context) -> JsResult { - Ok(JsValue::new(Date::$name())) - } - get_value - }}; -} - #[derive(Debug, Finalize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Date(Option); @@ -99,29 +84,27 @@ impl BuiltIn for Date { ) .name(Self::NAME) .length(Self::LENGTH) - .method(getter_method!(get_date), "getDate", 0) - .method(getter_method!(get_day), "getDay", 0) - .method(getter_method!(get_full_year), "getFullYear", 0) - .method(getter_method!(get_hours), "getHours", 0) - .method(getter_method!(get_milliseconds), "getMilliseconds", 0) - .method(getter_method!(get_minutes), "getMinutes", 0) - .method(getter_method!(get_month), "getMonth", 0) - .method(getter_method!(get_seconds), "getSeconds", 0) - .method(getter_method!(get_time), "getTime", 0) - .method(getter_method!(get_year), "getYear", 0) + .method(Self::get_date, "getDate", 0) + .method(Self::get_day, "getDay", 0) + .method(Self::get_full_year, "getFullYear", 0) + .method(Self::get_hours, "getHours", 0) + .method(Self::get_milliseconds, "getMilliseconds", 0) + .method(Self::get_minutes, "getMinutes", 0) + .method(Self::get_month, "getMonth", 0) + .method(Self::get_seconds, "getSeconds", 0) + .method(Self::get_time, "getTime", 0) .method(Self::get_timezone_offset, "getTimezoneOffset", 0) - .method(getter_method!(get_utc_date), "getUTCDate", 0) - .method(getter_method!(get_utc_day), "getUTCDay", 0) - .method(getter_method!(get_utc_full_year), "getUTCFullYear", 0) - .method(getter_method!(get_utc_hours), "getUTCHours", 0) - .method( - getter_method!(get_utc_milliseconds), - "getUTCMilliseconds", - 0, - ) - .method(getter_method!(get_utc_minutes), "getUTCMinutes", 0) - .method(getter_method!(get_utc_month), "getUTCMonth", 0) - .method(getter_method!(get_utc_seconds), "getUTCSeconds", 0) + .method(Self::get_utc_date, "getUTCDate", 0) + .method(Self::get_utc_day, "getUTCDay", 0) + .method(Self::get_utc_full_year, "getUTCFullYear", 0) + .method(Self::get_utc_hours, "getUTCHours", 0) + .method(Self::get_utc_milliseconds, "getUTCMilliseconds", 0) + .method(Self::get_utc_minutes, "getUTCMinutes", 0) + .method(Self::get_utc_month, "getUTCMonth", 0) + .method(Self::get_utc_seconds, "getUTCSeconds", 0) + .method(Self::get_year, "getYear", 0) + .static_method(Self::now, "now", 0) + .static_method(Self::parse, "parse", 1) .method(Self::set_date, "setDate", 1) .method(Self::set_full_year, "setFullYear", 3) .method(Self::set_hours, "setHours", 4) @@ -129,7 +112,6 @@ impl BuiltIn for Date { .method(Self::set_minutes, "setMinutes", 3) .method(Self::set_month, "setMonth", 2) .method(Self::set_seconds, "setSeconds", 2) - .method(Self::set_year, "setYear", 1) .method(Self::set_time, "setTime", 1) .method(Self::set_utc_date, "setUTCDate", 1) .method(Self::set_utc_full_year, "setUTCFullYear", 3) @@ -138,23 +120,26 @@ impl BuiltIn for Date { .method(Self::set_utc_minutes, "setUTCMinutes", 3) .method(Self::set_utc_month, "setUTCMonth", 2) .method(Self::set_utc_seconds, "setUTCSeconds", 2) + .method(Self::set_year, "setYear", 1) .method(Self::to_date_string, "toDateString", 0) - .method(getter_method!(to_gmt_string), "toGMTString", 0) + .method(Self::to_gmt_string, "toGMTString", 0) .method(Self::to_iso_string, "toISOString", 0) + // Why toJSON length is 1, does `method()`'s length signifies number of + // inputs? If so shouldn't it be 0? .method(Self::to_json, "toJSON", 1) - // Locale strings + .method(Self::to_locale_date_string, "toLocaleDateString", 0) + .method(Self::to_locale_string, "toLocaleString", 0) + .method(Self::to_locale_time_string, "toLocaleTimeString", 0) .method(Self::to_string, "toString", 0) .method(Self::to_time_string, "toTimeString", 0) - .method(getter_method!(to_utc_string), "toUTCString", 0) - .method(getter_method!(value_of), "valueOf", 0) + .method(Self::to_utc_string, "toUTCString", 0) + .static_method(Self::utc, "UTC", 7) + .method(Self::value_of, "valueOf", 0) .method( Self::to_primitive, (WellKnownSymbols::to_primitive(), "[Symbol.toPrimitive]"), 1, ) - .static_method(Self::now, "now", 0) - .static_method(Self::parse, "parse", 1) - .static_method(Self::utc, "UTC", 7) .build() .conv::() .pipe(Some) @@ -353,7 +338,7 @@ impl Date { .into()) } } - + /// Utility: Returns `Date` object with current datetime pub(crate) fn date_create(prototype: Option, context: &mut Context) -> JsObject { let prototype = prototype.unwrap_or_else(|| context.intrinsics().constructors().date().prototype()); @@ -555,8 +540,19 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getdate /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate - pub fn get_date(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| f64::from(dt.day())) + pub fn get_date(this: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.day())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getDay()` @@ -570,12 +566,19 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getday /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay - pub fn get_day(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| { - let weekday = dt.weekday() as u32; - let weekday = (weekday + 1) % 7; // 0 represents Monday in Chrono - f64::from(weekday) - }) + pub fn get_day(this: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.weekday().num_days_from_sunday())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getFullYear()` @@ -588,8 +591,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getfullyear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear - pub fn get_full_year(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| f64::from(dt.year())) + pub fn get_full_year( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.year())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getHours()` @@ -602,8 +620,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.gethours /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours - pub fn get_hours(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| f64::from(dt.hour())) + pub fn get_hours( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.hour())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getMilliseconds()` @@ -616,10 +649,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getmilliseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds - pub fn get_milliseconds(&self) -> f64 { - self.to_local().map_or(f64::NAN, |dt| { - f64::from(dt.nanosecond()) / NANOS_PER_MS as f64 - }) + pub fn get_milliseconds( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.timestamp_subsec_millis())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getMinutes()` @@ -632,9 +678,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getminutes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMinutes - pub fn get_minutes(&self) -> f64 { - self.to_local() - .map_or(f64::NAN, |dt| f64::from(dt.minute())) + pub fn get_minutes( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.minute())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getMonth()` @@ -648,9 +708,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getmonth /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth - pub fn get_month(&self) -> f64 { - self.to_local() - .map_or(f64::NAN, |dt| f64::from(dt.month0())) + pub fn get_month( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.month0())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getSeconds()` @@ -663,9 +737,23 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getSeconds - pub fn get_seconds(&self) -> f64 { - self.to_local() - .map_or(f64::NAN, |dt| f64::from(dt.second())) + pub fn get_seconds( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let date = Local::now() + .timezone() + .from_utc_datetime(&t) + .format("%Y-%m-%dT%H:%M:%S%.f%:z") + .to_string(); + let local = NaiveDateTime::parse_from_str(&date, "%Y-%m-%dT%H:%M:%S%.f%:z") + .expect("INFALLIBLE: Converting string built from `Local::now()` to NaiveDateTime"); + Ok(JsValue::new(local.second())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getYear()` @@ -680,9 +768,14 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getyear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear - pub fn get_year(&self) -> f64 { - self.to_local() - .map_or(f64::NAN, |dt| f64::from(dt.year()) - 1900f64) + pub fn get_year(this: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let local = Local::now().timezone().from_local_datetime(&t).unwrap(); + let year = JsValue::Integer(local.year()); + year.sub(&JsValue::from(1900), context) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getTime()` @@ -695,7 +788,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.gettime /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime - pub fn get_time(&self) -> f64 { + pub fn get_time(this: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.timestamp_millis())) + } else { + Ok(JsValue::nan()) + } + } + + /// Utility: Internal `get_time()` + fn int_get_time(&self) -> f64 { self.to_utc() .map_or(f64::NAN, |dt| dt.timestamp_millis() as f64) } @@ -741,8 +843,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcdate /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDate - pub fn get_utc_date(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.day())) + pub fn get_utc_date( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.day())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCDay()` @@ -756,12 +866,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcday /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDay - pub fn get_utc_day(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| { - let weekday = dt.weekday() as u32; - let weekday = (weekday + 1) % 7; // 0 represents Monday in Chrono - f64::from(weekday) - }) + pub fn get_utc_day( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.weekday().num_days_from_sunday())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCFullYear()` @@ -774,8 +888,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcfullyear /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear - pub fn get_utc_full_year(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.year())) + pub fn get_utc_full_year( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.year())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCHours()` @@ -788,8 +910,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutchours /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCHours - pub fn get_utc_hours(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.hour())) + pub fn get_utc_hours( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.hour())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCMilliseconds()` @@ -802,10 +932,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcmilliseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds - pub fn get_utc_milliseconds(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| { - f64::from(dt.nanosecond()) / NANOS_PER_MS as f64 - }) + pub fn get_utc_milliseconds( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.timestamp_subsec_millis())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCMinutes()` @@ -818,8 +954,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcminutes /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes - pub fn get_utc_minutes(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.minute())) + pub fn get_utc_minutes( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.minute())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCMonth()` @@ -833,8 +977,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcmonth /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth - pub fn get_utc_month(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.month0())) + pub fn get_utc_month( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.month0())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.getUTCSeconds()` @@ -847,8 +999,16 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.getutcseconds /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds - pub fn get_utc_seconds(&self) -> f64 { - self.to_utc().map_or(f64::NAN, |dt| f64::from(dt.second())) + pub fn get_utc_seconds( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.second())) + } else { + Ok(JsValue::nan()) + } } /// `Date.prototype.setDate()` @@ -877,7 +1037,7 @@ impl Date { t.set_components(false, None, None, Some(dt), None, None, None, None); // 4. Let u be TimeClip(UTC(newDate)). - let u = t.get_time(); + let u = t.int_get_time(); // 5. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -938,7 +1098,7 @@ impl Date { t.set_components(false, Some(y), m, dt, None, None, None, None); // 7. Let u be TimeClip(UTC(newDate)). - let u = t.get_time(); + let u = t.int_get_time(); // 8. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -995,7 +1155,7 @@ impl Date { t.set_components(false, None, None, None, Some(h), m, sec, milli); // 7. Let u be TimeClip(UTC(date)). - let u = t.get_time(); + let u = t.int_get_time(); // 8. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -1033,7 +1193,7 @@ impl Date { t.set_components(false, None, None, None, None, None, None, Some(ms)); // 4. Let u be TimeClip(UTC(MakeDate(Day(t), time))). - let u = t.get_time(); + let u = t.int_get_time(); // 5. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -1085,7 +1245,7 @@ impl Date { t.set_components(false, None, None, None, None, Some(m), s, milli); // 6. Let u be TimeClip(UTC(date)). - let u = t.get_time(); + let u = t.int_get_time(); // 7. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -1126,7 +1286,7 @@ impl Date { t.set_components(false, None, Some(m), dt, None, None, None, None); // 5. Let u be TimeClip(UTC(newDate)). - let u = t.get_time(); + let u = t.int_get_time(); // 6. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -1171,7 +1331,7 @@ impl Date { t.set_components(false, None, None, None, None, None, Some(s), milli); // 5. Let u be TimeClip(UTC(date)). - let u = t.get_time(); + let u = t.int_get_time(); // 6. Set the [[DateValue]] internal slot of this Date object to u. this.set_data(ObjectData::date(t)); @@ -1233,7 +1393,7 @@ impl Date { this.set_data(ObjectData::date(t)); // 11. Return the value of the [[DateValue]] internal slot of this Date object. - Ok(t.get_time().into()) + Ok(t.int_get_time().into()) } /// `Date.prototype.setTime()` @@ -1265,13 +1425,13 @@ impl Date { }; // 3. Let v be TimeClip(t). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 4. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 5. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCDate()` @@ -1303,13 +1463,13 @@ impl Date { t.set_components(true, None, None, Some(dt), None, None, None, None); // 4. Let v be TimeClip(newDate). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 5. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 6. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setFullYear()` @@ -1364,13 +1524,13 @@ impl Date { t.set_components(true, Some(y), m, dt, None, None, None, None); // 7. Let v be TimeClip(newDate). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 8. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 9. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCHours()` @@ -1425,13 +1585,13 @@ impl Date { t.set_components(true, None, None, None, Some(h), m, sec, ms); // 7. Let v be TimeClip(newDate). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 8. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 9. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCMilliseconds()` @@ -1463,13 +1623,13 @@ impl Date { t.set_components(true, None, None, None, None, None, None, Some(ms)); // 4. Let v be TimeClip(MakeDate(Day(t), time)). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 5. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 6. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCMinutes()` @@ -1519,13 +1679,13 @@ impl Date { t.set_components(true, None, None, None, None, Some(m), s, milli); // 8. Let v be TimeClip(date). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 9. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 10. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCMonth()` @@ -1566,13 +1726,13 @@ impl Date { t.set_components(true, None, Some(m), dt, None, None, None, None); // 6. Let v be TimeClip(newDate). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 7. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 8. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.setUTCSeconds()` @@ -1613,13 +1773,13 @@ impl Date { t.set_components(true, None, None, None, None, None, Some(s), milli); // 6. Let v be TimeClip(date). - let v = t.get_time(); + let v = Self::get_time(this, args, context)?; // 7. Set the [[DateValue]] internal slot of this Date object to v. this.set_data(ObjectData::date(t)); // 8. Return v. - Ok(v.into()) + Ok(v) } /// `Date.prototype.toDateString()` @@ -1657,6 +1817,25 @@ impl Date { } } + /// `Date.prototype.toLocaleDateString()` + /// + /// The `toLocaleDateString()` method returns the date portion of the given Date instance + /// according to language-specific conventions. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.tolocaledatestring + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString + pub fn to_locale_date_string( + _this: &JsValue, + _args: &[JsValue], + _context: &mut Context, + ) -> JsResult { + unimplemented!() + } + /// `Date.prototype.toGMTString()` /// /// The `toGMTString()` method converts a date to a string, using Internet Greenwich Mean Time (GMT) conventions. @@ -1667,8 +1846,12 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.togmtstring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toGMTString - pub fn to_gmt_string(self) -> String { - self.to_utc_string() + pub fn to_gmt_string( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + Self::to_utc_string(this, &[JsValue::Null], context) } /// `Date.prototype.toISOString()` @@ -1733,7 +1916,7 @@ impl Date { /// `Date.prototype.toString()` /// - /// The toString() method returns a string representing the specified Date object. + /// The `toString()` method returns a string representing the specified Date object. /// /// More information: /// - [ECMAScript reference][spec] @@ -1759,6 +1942,24 @@ impl Date { } } + /// `Date.prototype.toLocaleString()` + /// + /// The `toLocaleString()` method returns a string representing the specified Date object. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.tolocalestring + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString + pub fn to_locale_string( + _this: &JsValue, + _: &[JsValue], + _context: &mut Context, + ) -> JsResult { + unimplemented!() + } + /// `Date.prototype.toTimeString()` /// /// The `toTimeString()` method returns the time portion of a Date object in human readable form in American @@ -1795,6 +1996,25 @@ impl Date { } } + /// `Date.prototype.toLocaleTimeString()` + /// + /// The `toLocaleTimeString()` method returns the time portion of a Date object in human readable form in American + /// English. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.tolocaletimestring + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString + pub fn to_locale_time_string( + _this: &JsValue, + _args: &[JsValue], + _context: &mut Context, + ) -> JsResult { + unimplemented!() + } + /// `Date.prototype.toUTCString()` /// /// The `toUTCString()` method returns a string representing the specified Date object. @@ -1805,11 +2025,17 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.toutcstring /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString - pub fn to_utc_string(self) -> String { - self.to_utc().map_or_else( - || "Invalid Date".to_string(), - |date_time| date_time.format("%a, %d %b %Y %H:%M:%S GMT").to_string(), - ) + pub fn to_utc_string( + this: &JsValue, + _args: &[JsValue], + context: &mut Context, + ) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + let utc_string = t.format("%a, %d %b %Y %H:%M:%S GMT").to_string(); + Ok(JsValue::new(utc_string)) + } else { + context.throw_range_error("Invalid time value") + } } /// `Date.prototype.valueOf()` @@ -1822,8 +2048,12 @@ impl Date { /// /// [spec]: https://tc39.es/ecma262/#sec-date.prototype.valueof /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf - pub fn value_of(&self) -> f64 { - self.get_time() + pub fn value_of(this: &JsValue, _args: &[JsValue], context: &mut Context) -> JsResult { + if let Some(t) = this_time_value(this, context)?.0 { + Ok(JsValue::new(t.timestamp_millis())) + } else { + Ok(JsValue::nan()) + } } /// `Date.now()` @@ -1923,6 +2153,16 @@ impl Date { .and_then(|f| Self::time_clip(f.timestamp_millis() as f64)) .map_or(Ok(JsValue::nan()), |time| Ok(JsValue::new(time))) } + /// Utility: Returns an `Object` representing `Date` from string in RFC3339 + pub(crate) fn create_obj(value: &JsValue, context: &mut Context) -> JsObject { + let prototype = context.intrinsics().constructors().date().prototype(); + let date_time = DateTime::parse_from_rfc3339(&value.to_string(context).expect( + "Utility: Date's string conversion used in limited(internal) area shouldn't fail", + )) + .expect("Utility: Parse RFC3339 is used in limited(internal) areas shouldn't fail"); + let internal_date = Date(Some(date_time.naive_local())); + JsObject::from_proto_and_data(prototype, ObjectData::date(internal_date)) + } } /// The abstract operation `thisTimeValue` takes argument value. diff --git a/boa_engine/src/object/jsdate.rs b/boa_engine/src/object/jsdate.rs index 66b4035d1d2..8f514dca57e 100644 --- a/boa_engine/src/object/jsdate.rs +++ b/boa_engine/src/object/jsdate.rs @@ -51,174 +51,175 @@ impl JsDate { Date::utc(&JsValue::Null, values, context) } - // /// Returns the day of the month(1-31) for the specified date - // /// according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getDate()`. - // #[inline] - // pub fn get_date(&self, context: &mut Context) -> JsValue { - // Date::get_date(&self.inner.clone()).into() - // } - - // /// Returns the day of the week (0–6) for the specified date - // /// according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getDay()`. - // #[inline] - // pub fn get_day(&self, context: &mut Context) -> JsValue { - // Date::get_day(&self.inner.clone().into()).into() - // } - - // /// Returns the year (4 digits for 4-digit years) of the specified date - // /// according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getFullYear()`. - // #[inline] - // pub fn get_full_year(&self, context: &mut Context) -> JsValue { - // Date::get_full_year(&self.inner.clone().into()).into() - // } - - // /// Returns the hour (0–23) in the specified date according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getHours()`. - // #[inline] - // pub fn get_hours(&self, context: &mut Context) -> JsValue { - // Date::get_hours(self.inner.clone().into, context) - // } - - // /// Returns the milliseconds (0–999) in the specified date according - // /// to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getMilliseconds()`. - // #[inline] - // pub fn get_milliseconds(&self, context: &mut Context) -> JsValue { - // Date::get_milliseconds(self.inner.clone().into, context) - // } - - // /// Returns the minutes (0–59) in the specified date according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getMinutes()`. - // #[inline] - // pub fn get_minutes(&self, context: &mut Context) -> JsValue { - // Date::get_minutes(self.inner.clone().into, context) - // } - - // /// Returns the month (0–11) in the specified date according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getMonth()`. - // #[inline] - // pub fn get_month(&self, context: &mut Context) -> JsValue { - // Date::get_month(self.inner.clone().into, context) - // } - - // /// Returns the seconds (0–59) in the specified date according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getSeconds()`. - // #[inline] - // pub fn get_seconds(&self, context: &mut Context) -> JsValue { - // Date::get_seconds(self.inner.clone().into, context) - // } - - // /// Returns the numeric value of the specified date as the number - // /// of milliseconds since UNIX epoch. - // /// Negative values are returned for prior times. - // /// - // /// Same as JavaScript's `Date.prototype.getTime()`. - // #[inline] - // pub fn get_time(&self, context: &mut Context) -> JsValue { - // Date::get_time(self.inner.clone().into, context) - // } - - // /// Returns the time-zone offset in minutes for the current locale. - // /// - // /// Same as JavaScript's `Date.prototype.getTimezoneOffset()`. - // #[inline] - // pub fn get_timezone_offset(&self, context: &mut Context) -> JsValue { - // Date::get_timezone_offset(self.inner.clone().into, context) - // } - - // /// Returns the day (date) of the month (1–31) in the specified - // /// date according to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCDate()`. - // #[inline] - // pub fn get_utc_date(&self, context: &mut Context) -> JsValue { - // Date::get_utc_date(self.inner.clone().into, context) - // } - - // /// Returns the day of the week (0–6) in the specified - // /// date according to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCDay()`. - // #[inline] - // pub fn get_utc_day(&self, context: &mut Context) -> JsValue { - // Date::get_utc_day(self.inner.clone().into, context) - // } - - // /// Returns the year (4 digits for 4-digit years) in the specified - // /// date according to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCFullYear()`. - // #[inline] - // pub fn get_utc_full_year(&self, context: &mut Context) -> JsValue { - // Date::get_utc_full_year(self.inner.clone().into, context) - // } - - // /// Returns the hours (0–23) in the specified date according - // /// to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCHours()`. - // #[inline] - // pub fn get_utc_hours(&self, context: &mut Context) -> JsValue { - // Date::get_utc_hours(self.inner.clone().into, context) - // } - - // /// Returns the milliseconds (0–999) in the specified date - // /// according to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCMilliseconds()`. - // #[inline] - // pub fn get_utc_milliseconds(&self, context: &mut Context) -> JsValue { - // Date::get_utc_milliseconds(self.inner.clone().into, context) - // } - - // /// Returns the minutes (0–59) in the specified date according - // /// to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCMinutes()`. - // #[inline] - // pub fn get_utc_minutes(&self, context: &mut Context) -> JsValue { - // Date::get_utc_minutes(self.inner.clone().into, context) - // } - - // /// Returns the month (0–11) in the specified date according - // /// to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCMonth()`. - // #[inline] - // pub fn get_utc_month(&self, context: &mut Context) -> JsValue { - // Date::get_utc_month(self.inner.clone().into, context) - // } - - // /// Returns the seconds (0–59) in the specified date according - // /// to universal time. - // /// - // /// Same as JavaScript's `Date.prototype.getUTCSeconds()`. - // #[inline] - // pub fn get_utc_seconds(&self, context: &mut Context) -> JsValue { - // Date::get_utc_seconds(self.inner.clone().into, context) - // } - - // /// DEPRECATED: This feature is no longer recommended. - // /// USE: `get_full_year()` instead. - // /// Returns the year (usually 2–3 digits) in the specified date - // /// according to local time. - // /// - // /// Same as JavaScript's `Date.prototype.getYear()`. - // #[inline] - // pub fn get_year(&self, context: &mut Context) -> JsValue { - // Date::get_year(self.inner.clone().into, context) - // } + /// Returns the day of the month(1-31) for the specified date + /// according to local time. + /// + /// Same as JavaScript's `Date.prototype.getDate()`. + #[inline] + pub fn get_date(&self, context: &mut Context) -> JsResult { + Date::get_date(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the day of the week (0–6) for the specified date + /// according to local time. + /// + /// Same as JavaScript's `Date.prototype.getDay()`. + #[inline] + pub fn get_day(&self, context: &mut Context) -> JsResult { + Date::get_day(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the year (4 digits for 4-digit years) of the specified date + /// according to local time. + /// + /// Same as JavaScript's `Date.prototype.getFullYear()`. + #[inline] + pub fn get_full_year(&self, context: &mut Context) -> JsResult { + Date::get_full_year(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the hour (0–23) in the specified date according to local time. + /// + /// Same as JavaScript's `Date.prototype.getHours()`. + #[inline] + pub fn get_hours(&self, context: &mut Context) -> JsResult { + Date::get_hours(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the milliseconds (0–999) in the specified date according + /// to local time. + /// + /// Same as JavaScript's `Date.prototype.getMilliseconds()`. + #[inline] + pub fn get_milliseconds(&self, context: &mut Context) -> JsResult { + Date::get_milliseconds(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the minutes (0–59) in the specified date according to local time. + /// + /// Same as JavaScript's `Date.prototype.getMinutes()`. + #[inline] + pub fn get_minutes(&self, context: &mut Context) -> JsResult { + Date::get_minutes(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the month (0–11) in the specified date according to local time. + /// + /// Same as JavaScript's `Date.prototype.getMonth()`. + #[inline] + pub fn get_month(&self, context: &mut Context) -> JsResult { + Date::get_month(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the seconds (0–59) in the specified date according to local time. + /// + /// Same as JavaScript's `Date.prototype.getSeconds()`. + #[inline] + pub fn get_seconds(&self, context: &mut Context) -> JsResult { + Date::get_seconds(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the numeric value of the specified date as the number + /// of milliseconds since UNIX epoch. + /// Negative values are returned for prior times. + /// + /// Same as JavaScript's `Date.prototype.getTime()`. + #[inline] + pub fn get_time(&self, context: &mut Context) -> JsResult { + Date::get_time(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the time-zone offset in minutes for the current locale. + /// + /// Same as JavaScript's `Date.prototype.getTimezoneOffset()`. + #[inline] + pub fn get_timezone_offset(&self, context: &mut Context) -> JsResult { + Date::get_timezone_offset(&self.inner.clone().into(), &[JsValue::Null], context) + } + + /// Returns the day (date) of the month (1–31) in the specified + /// date according to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCDate()`. + #[inline] + pub fn get_utc_date(&self, context: &mut Context) -> JsResult { + Date::get_utc_date(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the day of the week (0–6) in the specified + /// date according to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCDay()`. + #[inline] + pub fn get_utc_day(&self, context: &mut Context) -> JsResult { + Date::get_utc_day(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the year (4 digits for 4-digit years) in the specified + /// date according to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCFullYear()`. + #[inline] + pub fn get_utc_full_year(&self, context: &mut Context) -> JsResult { + Date::get_utc_full_year(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the hours (0–23) in the specified date according + /// to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCHours()`. + #[inline] + pub fn get_utc_hours(&self, context: &mut Context) -> JsResult { + Date::get_utc_hours(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the milliseconds (0–999) in the specified date + /// according to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCMilliseconds()`. + #[inline] + pub fn get_utc_milliseconds(&self, context: &mut Context) -> JsResult { + Date::get_utc_milliseconds(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the minutes (0–59) in the specified date according + /// to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCMinutes()`. + #[inline] + pub fn get_utc_minutes(&self, context: &mut Context) -> JsResult { + Date::get_utc_minutes(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the month (0–11) in the specified date according + /// to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCMonth()`. + #[inline] + pub fn get_utc_month(&self, context: &mut Context) -> JsResult { + Date::get_utc_month(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// Returns the seconds (0–59) in the specified date according + /// to universal time. + /// + /// Same as JavaScript's `Date.prototype.getUTCSeconds()`. + #[inline] + pub fn get_utc_seconds(&self, context: &mut Context) -> JsResult { + Date::get_utc_seconds(&self.inner.clone().into(), &[JsValue::null()], context) + } + + /// DEPRECATED: This feature is no longer recommended. + /// USE: `get_full_year()` instead. + /// Returns the year (usually 2–3 digits) in the specified date + /// according to local time. + /// + /// Same as JavaScript's `Date.prototype.getYear()`. + #[deprecated] + #[inline] + pub fn get_year(&self, context: &mut Context) -> JsResult { + Date::get_year(&self.inner.clone().into(), &[JsValue::null()], context) + } /// Sets the day of the month for a specified date according /// to local time. @@ -417,6 +418,7 @@ impl JsDate { /// the UNIX epoch. /// /// Same as JavaScript's legacy `Date.prototype.setYear()`. + #[deprecated] #[inline] pub fn set_year(&self, value: T, context: &mut Context) -> JsResult where @@ -433,6 +435,17 @@ impl JsDate { Date::to_date_string(&self.inner.clone().into(), &[JsValue::Null], context) } + /// DEPRECATED: This feature is no longer recommended. + /// USE: `to_utc_string()` instead. + /// Returns a string representing the Date based on the GMT timezone. + /// + /// Same as JavaScript's legacy `Date.prototype.toGMTString()` + #[deprecated] + #[inline] + pub fn to_gmt_string(&self, context: &mut Context) -> JsResult { + Date::to_gmt_string(&self.inner.clone().into(), &[JsValue::Null], context) + } + /// Returns the given date in the ISO 8601 format according to universal /// time. /// @@ -441,6 +454,7 @@ impl JsDate { pub fn to_iso_string(&self, context: &mut Context) -> JsResult { Date::to_iso_string(&self.inner.clone().into(), &[JsValue::Null], context) } + /// Returns a string representing the Date using `to_iso_string()`. /// /// Same as JavaScript's `Date.prototype.toJSON()`. @@ -449,28 +463,40 @@ impl JsDate { Date::to_json(&self.inner.clone().into(), &[JsValue::Null], context) } - // /// DEPRECATED: This feature is no longer recommended. - // /// USE: `to_utc_string()` instead. - // /// Returns a string representing the Date based on the GMT timezone. - // /// - // /// Same as JavaScript's legacy `Date.prototype.toGMTString()` - // #[inline] - // pub fn to_gmt_string(&self, context: &mut Context) -> JsValue { - // Date::to_gmt_string(&self.inner.clone().into(), &[JsValue::Null], context).into() - // } - - // /// Returns a string representing the date portion of the given Date instance - // /// according to language-specific conventions. - // /// - // /// Same as JavaScript's `Date.prototype.toLocaleDateString()`. - // #[inline] - // pub fn to_local_date_string(&self, values: &[JsValue], context: &mut Context) -> JsValue {} - - // /// Returns a string representing the given date according to language-specific conventions. - // /// - // /// Same as JavaScript's `Date.prototype.toLocaleDateString()`. - // #[inline] - // pub fn to_local_string(&self, values: &[JsValue], context: &mut Context) -> JsValue {} + /// Returns a string representing the date portion of the given Date instance + /// according to language-specific conventions. + /// Takes [locales, options] + /// + /// Same as JavaScript's `Date.prototype.toLocaleDateString()`. + #[inline] + pub fn to_local_date_string( + &self, + values: &[JsValue], + context: &mut Context, + ) -> JsResult { + Date::to_locale_date_string(&self.inner.clone().into(), values, context) + } + + /// Returns a string representing the given date according to language-specific conventions. + /// Takes [locales, options] + /// + /// Same as JavaScript's `Date.prototype.toLocaleDateString()`. + #[inline] + pub fn to_locale_string(&self, values: &[JsValue], context: &mut Context) -> JsResult { + Date::to_locale_string(&self.inner.clone().into(), values, context) + } + + /// Returns the "time" portion of the Date as human-readable string. + /// + /// Same as JavaScript's `Date.prototype.toTimeString()`. + #[inline] + pub fn to_locale_time_string( + &self, + values: &[JsValue], + context: &mut Context, + ) -> JsResult { + Date::to_locale_time_string(&self.inner.clone().into(), values, context) + } /// Returns a string representing the specified Date object. /// @@ -488,22 +514,28 @@ impl JsDate { Date::to_time_string(&self.inner.clone().into(), &[JsValue::Null], context) } - // /// Returns a string representing the given date using the UTC time zone. - // /// - // /// Same as JavaScript's `Date.prototype.toUTCString()`. - // DEBUG: same self issue <======================================================== - // #[inline] - // pub fn to_utc_string(&self, context: &mut Context) -> JsResult { - // Date::to_utc_string(&self.inner.clone().into(), &[JsValue::Null], context) - // } - - // /// Returns the primitive value pf Date object. - // /// - // /// Same as JavaScript's `Date.prototype.valueOf()`. - // #[inline] - // pub fn value_of(&self, context: &mut Context) -> JsValue { - // Date::value_of(self.inner.clone().into(), context) - // } + /// Returns a string representing the given date using the UTC time zone. + /// + /// Same as JavaScript's `Date.prototype.toUTCString()`. + #[inline] + pub fn to_utc_string(&self, context: &mut Context) -> JsResult { + Date::to_utc_string(&self.inner.clone().into(), &[JsValue::Null], context) + } + + /// Returns the primitive value pf Date object. + /// + /// Same as JavaScript's `Date.prototype.valueOf()`. + #[inline] + pub fn value_of(&self, context: &mut Context) -> JsResult { + Date::value_of(&self.inner.clone().into(), &[JsValue::Null], context) + } + + /// Utility create a `Date` object from RFC3339 string + #[inline] + pub fn new_from_parse(value: &JsValue, context: &mut Context) -> Self { + let inner = Date::create_obj(value, context); + Self { inner } + } } impl From for JsObject {