mirror of https://github.com/boa-dev/boa.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Tree:
4493254de7
add-vhs-ci
benchmarks
control-flow-graph
expect-lints
feature/node_span
feature/snapshot
features
gh-readonly-queue/main/pr-2877-b0ddf5eed00a53281d67fc7d846233fc0d99ce9c
gh-readonly-queue/main/pr-3144-8e48cec73fae708420b9af88813d4870243c491a
main
nan-boxing
optimization/static-shapes
real_conformance
reduce-environment-allocations
refactor/interner
refactor/register-vm
release-0.20
releases/0.17
releases/0.19
semver_checks
tco
utility-crate
wasm-debugger
nightly
v0.10
v0.11
v0.12
v0.13
v0.14
v0.15
v0.16
v0.17
v0.17.1
v0.17.2
v0.17.3
v0.18
v0.19
v0.19.1
v0.2.0
v0.2.1
v0.3.0
v0.4.0
v0.5.0
v0.5.1
v0.6.0
v0.7.0
v0.8.0
v0.9.0
${ noResults }
boa/boa_examples
Anuvrat
70f73b45d8
This PR adds a safe wrapper around JavaScript `JsDate` from `builtins::date`, and is being tracked at #2098. #### Implements following methods - [x] `new Date()` - [x] `Date.prototype.getDate()` - [x] `Date.prototype.getDay()` - [x] `Date.prototype.getFullYear()` - [x] `Date.prototype.getHours()` - [x] `Date.prototype.getMilliseconds()` - [x] `Date.prototype.getMinutes()` - [x] `Date.prototype.getMonth()` - [x] `Date.prototype.getSeconds()` - [x] `Date.prototype.getTime()` - [x] `Date.prototype.getTimezoneOffset()` - [x] `Date.prototype.getUTCDate()` - [x] `Date.prototype.getUTCDay()` - [x] `Date.prototype.getUTCFullYear()` - [x] `Date.prototype.getUTCHours()` - [x] `Date.prototype.getUTCMilliseconds()` - [x] `Date.prototype.getUTCMinutes()` - [x] `Date.prototype.getUTCMonth()` - [x] `Date.prototype.getUTCSeconds()` - [x] `Date.prototype.getYear()` - [x] `Date.now()` - [ ] `Date.parse()` Issue 4 - [x] `Date.prototype.setDate()` - [x] `Date.prototype.setFullYear()` - [ ] `Date.prototype.setHours()` Issue 3 - [x] `Date.prototype.setMilliseconds()` - [ ] `Date.prototype.setMinutes()` Issue 3 - [x] `Date.prototype.setMonth()` - [x] `Date.prototype.setSeconds()` - [x] `Date.prototype.setTime()` - [x] `Date.prototype.setUTCDate()` - [x] `Date.prototype.setUTCFullYear()` - [x] `Date.prototype.setUTCHours()` - [x] `Date.prototype.setUTCMilliseconds()` - [x] `Date.prototype.setUTCMinutes()` - [x] `Date.prototype.setUTCMonth()` - [x] `Date.prototype.setUTCSeconds()` - [x] `Date.prototype.setYear()` - [ ] `Date.prototype.toDateString()` Issue 5 - [ ] `Date.prototype.toGMTString()` Issue 5 - [ ] `Date.prototype.toISOString()` Issue 5 - [ ] `Date.prototype.toJSON()` Issue 5 - [ ] `Date.prototype.toLocaleDateString()` Issue 5 and 6 - [ ] `Date.prototype.toLocaleString()` Issue 5 and 6 - [ ] `Date.prototype.toLocaleTimeString()` Issue 5 and 6 - [ ] `Date.prototype.toString()` Issue 5 - [ ] `Date.prototype.toTimeString()` Issue 5 - [ ] `Date.prototype.toUTCString()` Issue 5 - [x] `Date.UTC()` - [x] `Date.prototype.valueOf()` ### Issues 1. ~~`get_*()` and some other methods - They take `&self` as input internally, and internal struct shouldn't be used in a wrapper API. Therefore, these would require input to be `this: &JsValue, args: &[JsValue], context: &mut Context` like others and use `this_time_value()`?~~ Fixed using `this_time_value()` 2. ~~`to_string()`- how can I use `Date::to_string()` rather than `alloc::string::ToString`.~~ My bad it compiles, just `rust-analyzer` was showing it as an issue. 3. `set_hours()` and `set_minutes()` - they subtract local timezones when setting the value, e.g. - On further look: ```rust // both function call `builtins:📅:mod.rs#L1038 this.set_data(ObjectData::date(t)); // `ObjectData::date` creates a new `Date` object `object::mods.rs#L423 // | this date is chrono::Date<Tz(TimezoneOffset)> and Tz default is being used here which is GMT+0 pub fn date(date: Date) -> Self { Self { kind: ObjectKind::Date(date), internal_methods: &ORDINARY_INTERNAL_METHODS, } } ``` - BTW, in `object::mod.rs`'s `enum ObjectKind` there is `Date(chrono::Date)` and it requires the generic argument, how is it being bypassed here? - Also in `set_minutes()` step 6, `LocalTime` should be used. ```rust // reference date = 2000-01-01T06:26:53.984 date.set_hours(&[23.into(), 23.into(), 23.into(), 23.into()], context)?; // would add tiemzone(+5:30) to it // Is 2000-01-01T17:53:23.023 // Should be 2000-01-01T23:23:23.023 ``` 4. `parse()` - it uses `chrono::parse_from_rfc3339` internally, while es6 spec recommends ISO8601. And it can also parse other formats like from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) `04 Dec 1995 00:12:00 GMT` which fails. So what should be done about it. 5. `to_*()` - This is more general, as the internal date object uses `chrono::NaiveDateTime` which doesn't have timezone. It doesn't account for `+4:00` in example below. ```rust // Creates new `Date` object from given rfc3339 string. let date = JsDate::new_from_parse(&JsValue::new("2018-01-26T18:30:09.453+04:00"), context); println!("to_string: {:?}", date2.to_string(context)?); // IS: Sat Jan 27 2018 00:00:09 GMT+0530 // Should: Fri Jan 26 2018 20:00:09 GMT+0530 ``` 6. `to_locale_*()` - requires [`ToDateTimeOptions`](https://402.ecma-international.org/9.0/#sec-todatetimeoptions) and localization would require chrono's `unstable-locales` feature, which is available for `DateTime` and not for `NaiveDateTime`. - I should have looked properly, `to_date_time_options` is already implemented in `builtins::intl`. Anyway, I would still need some tips on how to use it. What would function signature be like in wrapper API, how would `options` be passed to the said API. - So `to_date_time_options()` takes `options: &JsValue` as an argument and build an object from it and fetch properties through `Object.get()`. If I want `options` to be `{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }` what would `JsValue` look like to make it all work. ```rust date.to_locale_date_string(&[JsValue::new("en_EN"), OPTIONS], context)?; // OPTIONS need to be a JsValue which when converted into an object // have these properties { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; ``` ### Possible improvements 1. Right now, `object::jsdate::set_full_year()` and alike (input is a slice) are like below, `into()` doesn't feel ergonomic. ```rust #[inline] pub fn set_full_year(&self, values: &[JsValue], context: &mut Context) -> JsResult<JsValue> { Date::set_full_year(&self.inner.clone().into(), values, context) } // Usage date.set_full_year(&[2000.into(), 0.into(), 1.into()], context)?; // How can something like this be made to work #[inline] pub fn set_full_year<T>(&self, values: &[T], context: &mut Context) -> JsResult<JsValue> where T: Into<JsValue>, { | expected reference `&[value::JsValue]` | found reference `&[T]` Date::set_full_year(&self.inner.clone().into(), values, context) } ``` 2. Any other suggestion? |
2 years ago | |
---|---|---|
.. | ||
scripts | Added boa examples (#1161) | 3 years ago |
src/bin | Safe wrapper for `JsDate` (#2181) | 2 years ago |
Cargo.toml | Extract the parser into a crate (#2409) | 2 years ago |