quickjs_runtime/quickjs_utils/
dates.rs1use crate::jsutils::JsError;
4use crate::quickjs_utils;
5#[cfg(feature = "bellard")]
6use crate::quickjs_utils::class_ids::JS_CLASS_DATE;
7use crate::quickjs_utils::{functions, primitives};
8use crate::quickjsrealmadapter::QuickJsRealmAdapter;
9use crate::quickjsvalueadapter::QuickJsValueAdapter;
10use libquickjs_sys as q;
11#[cfg(feature = "bellard")]
12use libquickjs_sys::JS_GetClassID;
13#[cfg(feature = "quickjs-ng")]
14use libquickjs_sys::JS_IsDate;
15
16pub fn new_date_q(context: &QuickJsRealmAdapter) -> Result<QuickJsValueAdapter, JsError> {
18 unsafe { new_date(context.context) }
19}
20
21pub unsafe fn new_date(context: *mut q::JSContext) -> Result<QuickJsValueAdapter, JsError> {
25 let constructor = quickjs_utils::get_constructor(context, "Date")?;
26 let date_ref = functions::call_constructor(context, &constructor, &[])?;
27 Ok(date_ref)
28}
29
30pub fn is_date_q(context: &QuickJsRealmAdapter, obj_ref: &QuickJsValueAdapter) -> bool {
32 unsafe { is_date(context.context, obj_ref) }
33}
34
35#[allow(unused_variables)]
39pub unsafe fn is_date(ctx: *mut q::JSContext, obj: &QuickJsValueAdapter) -> bool {
40 #[cfg(feature = "bellard")]
41 {
42 JS_GetClassID(*obj.borrow_value()) == JS_CLASS_DATE
43 }
44 #[cfg(feature = "quickjs-ng")]
45 {
46 JS_IsDate(*obj.borrow_value())
47 }
48}
49
50pub fn set_time_q(
52 context: &QuickJsRealmAdapter,
53 date_ref: &QuickJsValueAdapter,
54 timestamp: f64,
55) -> Result<(), JsError> {
56 unsafe { set_time(context.context, date_ref, timestamp) }
57}
58
59pub unsafe fn set_time(
63 context: *mut q::JSContext,
64 date_ref: &QuickJsValueAdapter,
65 timestamp: f64,
66) -> Result<(), JsError> {
67 functions::invoke_member_function(
68 context,
69 date_ref,
70 "setTime",
71 &[primitives::from_f64(timestamp)],
72 )?;
73 Ok(())
74}
75pub fn get_time_q(
77 context: &QuickJsRealmAdapter,
78 date_ref: &QuickJsValueAdapter,
79) -> Result<f64, JsError> {
80 unsafe { get_time(context.context, date_ref) }
81}
82pub unsafe fn get_time(
86 context: *mut q::JSContext,
87 date_ref: &QuickJsValueAdapter,
88) -> Result<f64, JsError> {
89 let time_ref = functions::invoke_member_function(context, date_ref, "getTime", &[])?;
90 if time_ref.is_f64() {
91 primitives::to_f64(&time_ref)
92 } else if time_ref.is_i32() {
93 primitives::to_i32(&time_ref).map(|i| i as f64)
94 } else {
95 Err(JsError::new_string(format!(
96 "could not get time, val was a {}",
97 time_ref.get_js_type()
98 )))
99 }
100}
101
102#[cfg(test)]
103pub mod tests {
104 use crate::facades::tests::init_test_rt;
105 use crate::quickjs_utils::dates;
106 use crate::quickjs_utils::dates::{get_time_q, is_date_q, set_time_q};
107
108 #[test]
109 fn test_date() {
110 let rt = init_test_rt();
111 rt.exe_rt_task_in_event_loop(|q_js_rt| {
112 let q_ctx = q_js_rt.get_main_realm();
113 let date_ref = dates::new_date_q(q_ctx).expect("new_date failed");
114 assert!(is_date_q(q_ctx, &date_ref));
115
116 set_time_q(q_ctx, &date_ref, 1746776901898f64).expect("could not set time");
117 log::info!(
118 "date_str={}",
119 date_ref.to_string().expect("could not get date_ref string")
120 );
121 let gt_res = get_time_q(q_ctx, &date_ref);
122 match gt_res {
123 Ok(t) => {
124 assert_eq!(t, 1746776901898f64);
125 }
126 Err(e) => {
127 panic!("get time failed: {}", e);
128 }
129 }
130
131 set_time_q(q_ctx, &date_ref, 2f64).expect("could not set time");
132 let gt_res = get_time_q(q_ctx, &date_ref);
133 match gt_res {
134 Ok(t) => {
135 assert_eq!(t, 2f64);
136 }
137 Err(e) => {
138 panic!("get time 2 failed: {}", e);
139 }
140 }
141 });
142 }
143}