formualizer_eval/builtins/datetime/
today_now.rs1use super::serial::{date_to_serial_for, datetime_to_serial_for};
4use crate::function::Function;
5use crate::traits::{ArgumentHandle, FunctionContext};
6use formualizer_common::{ExcelError, LiteralValue};
7use formualizer_macros::func_caps;
8
9#[derive(Debug)]
11pub struct TodayFn;
12
13impl Function for TodayFn {
14 func_caps!(VOLATILE);
15
16 fn name(&self) -> &'static str {
17 "TODAY"
18 }
19
20 fn min_args(&self) -> usize {
21 0
22 }
23
24 fn eval_scalar<'a, 'b>(
25 &self,
26 _args: &'a [ArgumentHandle<'a, 'b>],
27 ctx: &dyn FunctionContext,
28 ) -> Result<LiteralValue, ExcelError> {
29 let today = ctx.timezone().today();
30 let serial = date_to_serial_for(ctx.date_system(), &today);
31 Ok(LiteralValue::Number(serial))
32 }
33}
34
35#[derive(Debug)]
37pub struct NowFn;
38
39impl Function for NowFn {
40 func_caps!(VOLATILE);
41
42 fn name(&self) -> &'static str {
43 "NOW"
44 }
45
46 fn min_args(&self) -> usize {
47 0
48 }
49
50 fn eval_scalar<'a, 'b>(
51 &self,
52 _args: &'a [ArgumentHandle<'a, 'b>],
53 ctx: &dyn FunctionContext,
54 ) -> Result<LiteralValue, ExcelError> {
55 let now = ctx.timezone().now();
56 let serial = datetime_to_serial_for(ctx.date_system(), &now);
57 Ok(LiteralValue::Number(serial))
58 }
59}
60
61pub fn register_builtins() {
62 use std::sync::Arc;
63 crate::function_registry::register_function(Arc::new(TodayFn));
64 crate::function_registry::register_function(Arc::new(NowFn));
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::test_workbook::TestWorkbook;
71 use std::sync::Arc;
72
73 #[test]
74 fn test_today_volatility() {
75 let wb = TestWorkbook::new().with_function(Arc::new(TodayFn));
76 let ctx = wb.interpreter();
77 let f = ctx.context.get_function("", "TODAY").unwrap();
78
79 let result = f.dispatch(&[], &ctx.function_context(None)).unwrap();
81 match result {
82 LiteralValue::Number(n) => {
83 assert!(n > 0.0);
85 assert_eq!(n.trunc(), n);
87 }
88 _ => panic!("TODAY should return a number"),
89 }
90
91 }
93
94 #[test]
95 fn test_now_volatility() {
96 let wb = TestWorkbook::new().with_function(Arc::new(NowFn));
97 let ctx = wb.interpreter();
98 let f = ctx.context.get_function("", "NOW").unwrap();
99
100 let result = f.dispatch(&[], &ctx.function_context(None)).unwrap();
102 match result {
103 LiteralValue::Number(n) => {
104 assert!(n > 0.0);
106 }
110 _ => panic!("NOW should return a number"),
111 }
112
113 }
115}