Skip to content

Commit b88f9f5

Browse files
authored
Add Date::new() and Date::value_of() (#452)
1 parent 1009103 commit b88f9f5

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

src/binding.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,23 @@ const v8::Array* v8__Array__New_with_elements(v8::Isolate* isolate,
852852

853853
uint32_t v8__Array__Length(const v8::Array& self) { return self.Length(); }
854854

855+
const v8::Date* v8__Date__New(const v8::Context& context, double time) {
856+
// v8::Date::New() is kind of weird in that it returns a v8::Value,
857+
// not a v8::Date, even though the object is always a Date object.
858+
// Let's paper over that quirk here.
859+
v8::MaybeLocal<v8::Date> maybe_date;
860+
861+
v8::Local<v8::Value> value;
862+
if (v8::Date::New(ptr_to_local(&context), time).ToLocal(&value)) {
863+
assert(value->IsDate());
864+
maybe_date = value.As<v8::Date>();
865+
}
866+
867+
return maybe_local_to_ptr(maybe_date);
868+
}
869+
870+
double v8__Date__ValueOf(const v8::Date& self) { return self.ValueOf(); }
871+
855872
const v8::External* v8__External__New(v8::Isolate* isolate, void* value) {
856873
return local_to_ptr(v8::External::New(isolate, value));
857874
}

src/date.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2019-2020 the Deno authors. All rights reserved. MIT license.
2+
3+
use crate::Context;
4+
use crate::Date;
5+
use crate::HandleScope;
6+
use crate::Local;
7+
8+
extern "C" {
9+
fn v8__Date__New(context: *const Context, value: f64) -> *const Date;
10+
fn v8__Date__ValueOf(this: *const Date) -> f64;
11+
}
12+
13+
/// An instance of the built-in Date constructor (ECMA-262, 15.9).
14+
impl Date {
15+
pub fn new<'s>(
16+
scope: &mut HandleScope<'s>,
17+
value: f64,
18+
) -> Option<Local<'s, Date>> {
19+
unsafe {
20+
scope.cast_local(|sd| v8__Date__New(sd.get_current_context(), value))
21+
}
22+
}
23+
24+
/// A specialization of Value::NumberValue that is more efficient
25+
/// because we know the structure of this object.
26+
pub fn value_of(&self) -> f64 {
27+
unsafe { v8__Date__ValueOf(self) }
28+
}
29+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ mod array_buffer;
3737
mod array_buffer_view;
3838
mod context;
3939
mod data;
40+
mod date;
4041
mod exception;
4142
mod external;
4243
mod external_references;

tests/test_api.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3485,3 +3485,33 @@ fn synthetic_module() {
34853485
check("a", 1.0);
34863486
check("b", 2.0);
34873487
}
3488+
3489+
#[allow(clippy::float_cmp)]
3490+
#[test]
3491+
fn date() {
3492+
let time = 1_291_404_900_000.; // 2010-12-03 20:35:00 - Mees <3
3493+
3494+
let _setup_guard = setup();
3495+
let isolate = &mut v8::Isolate::new(Default::default());
3496+
3497+
let scope = &mut v8::HandleScope::new(isolate);
3498+
3499+
let context = v8::Context::new(scope);
3500+
let scope = &mut v8::ContextScope::new(scope, context);
3501+
3502+
let date = v8::Date::new(scope, time).unwrap();
3503+
assert_eq!(date.value_of(), time);
3504+
3505+
let key = v8::String::new(scope, "d").unwrap();
3506+
context.global(scope).set(scope, key.into(), date.into());
3507+
3508+
let result = eval(scope, "d.toISOString()").unwrap();
3509+
let result = result.to_string(scope).unwrap();
3510+
let result = result.to_rust_string_lossy(scope);
3511+
assert_eq!(result, "2010-12-03T19:35:00.000Z");
3512+
3513+
// V8 chops off fractions.
3514+
let date = v8::Date::new(scope, std::f64::consts::PI).unwrap();
3515+
assert_eq!(date.value_of(), 3.0);
3516+
assert_eq!(date.number_value(scope).unwrap(), 3.0);
3517+
}

0 commit comments

Comments
 (0)