diff --git a/numbat/src/ffi.rs b/numbat/src/ffi.rs index c9870f92..ec7d8130 100644 --- a/numbat/src/ffi.rs +++ b/numbat/src/ffi.rs @@ -2,8 +2,6 @@ use std::collections::HashMap; use std::sync::OnceLock; -use chrono::Offset; - use crate::currency::ExchangeRatesCache; use crate::interpreter::RuntimeError; use crate::pretty_print::PrettyPrint; @@ -834,11 +832,9 @@ fn chr(args: &[Value]) -> Result { fn now(args: &[Value]) -> Result { assert!(args.is_empty()); - let now = chrono::Utc::now(); - - let offset = now.with_timezone(&chrono::Local).offset().fix(); + let now = chrono::Local::now().fixed_offset(); - Ok(Value::DateTime(now, offset)) + Ok(Value::DateTime(now)) } fn datetime(args: &[Value]) -> Result { @@ -850,9 +846,7 @@ fn datetime(args: &[Value]) -> Result { .map_err(RuntimeError::DateParsingError)? .ok_or(RuntimeError::DateParsingErrorUnknown)?; - let offset = crate::datetime::local_offset_for_datetime(&output); - - Ok(Value::DateTime(output.into(), offset)) + Ok(Value::DateTime(output)) } fn format_datetime(args: &[Value]) -> Result { @@ -901,8 +895,9 @@ fn from_unixtime(args: &[Value]) -> Result { let timestamp = args[0].unsafe_as_quantity().unsafe_value().to_f64() as i64; - let dt = chrono::DateTime::from_timestamp(timestamp, 0).unwrap(); - let offset = dt.offset().fix(); + let dt = chrono::DateTime::from_timestamp(timestamp, 0) + .unwrap() + .fixed_offset(); - Ok(Value::DateTime(dt, offset)) + Ok(Value::DateTime(dt)) } diff --git a/numbat/src/value.rs b/numbat/src/value.rs index 123e262c..35df2efb 100644 --- a/numbat/src/value.rs +++ b/numbat/src/value.rs @@ -1,3 +1,5 @@ +use chrono::FixedOffset; + use crate::{pretty_print::PrettyPrint, quantity::Quantity}; #[derive(Debug, Clone, PartialEq, Eq)] @@ -26,7 +28,7 @@ pub enum Value { Boolean(bool), String(String), /// A DateTime with an associated offset used when pretty printing - DateTime(chrono::DateTime, chrono::FixedOffset), + DateTime(chrono::DateTime), FunctionReference(FunctionReference), } @@ -59,8 +61,8 @@ impl Value { } #[track_caller] - pub fn unsafe_as_datetime(&self) -> &chrono::DateTime { - if let Value::DateTime(dt, _) = self { + pub fn unsafe_as_datetime(&self) -> &chrono::DateTime { + if let Value::DateTime(dt) = self { dt } else { panic!("Expected value to be a string"); @@ -83,7 +85,7 @@ impl std::fmt::Display for Value { Value::Quantity(q) => write!(f, "{}", q), Value::Boolean(b) => write!(f, "{}", b), Value::String(s) => write!(f, "\"{}\"", s), - Value::DateTime(dt, _) => write!(f, "datetime(\"{}\")", dt), + Value::DateTime(dt) => write!(f, "datetime(\"{}\")", dt), Value::FunctionReference(r) => write!(f, "{}", r), } } @@ -95,11 +97,7 @@ impl PrettyPrint for Value { Value::Quantity(q) => q.pretty_print(), Value::Boolean(b) => b.pretty_print(), Value::String(s) => s.pretty_print(), - Value::DateTime(dt, offset) => { - let l: chrono::DateTime = - chrono::DateTime::from_naive_utc_and_offset(dt.naive_utc(), *offset); - crate::markup::string(l.to_rfc2822()) - } + Value::DateTime(dt) => crate::markup::string(dt.to_rfc2822()), Value::FunctionReference(r) => crate::markup::string(r.to_string()), } } diff --git a/numbat/src/vm.rs b/numbat/src/vm.rs index e70f96c2..2974f595 100644 --- a/numbat/src/vm.rs +++ b/numbat/src/vm.rs @@ -533,9 +533,9 @@ impl Vm { } #[track_caller] - fn pop_datetime(&mut self) -> chrono::DateTime { + fn pop_datetime(&mut self) -> chrono::DateTime { match self.pop() { - Value::DateTime(q, _) => q, + Value::DateTime(q) => q, _ => panic!("Expected datetime to be on the top of the stack"), } } @@ -664,18 +664,15 @@ impl Vm { (seconds_f.fract() * 1_000_000_000f64).round() as i64, ); - self.push(Value::DateTime( - match op { - Op::AddToDateTime => lhs - .checked_add_signed(duration) - .ok_or(RuntimeError::DateTimeOutOfRange)?, - Op::SubFromDateTime => lhs - .checked_sub_signed(duration) - .ok_or(RuntimeError::DateTimeOutOfRange)?, - _ => unreachable!(), - }, - chrono::Local::now().offset().fix(), - )); + self.push(Value::DateTime(match op { + Op::AddToDateTime => lhs + .checked_add_signed(duration) + .ok_or(RuntimeError::DateTimeOutOfRange)?, + Op::SubFromDateTime => lhs + .checked_sub_signed(duration) + .ok_or(RuntimeError::DateTimeOutOfRange)?, + _ => unreachable!(), + })); } Op::DiffDateTime => { let unit = self.pop_quantity(); @@ -852,9 +849,9 @@ impl Vm { .parse() .map_err(|_| RuntimeError::UnknownTimezone(tz_name.into()))?; - let offset = dt.with_timezone(&tz).offset().fix(); + let dt = dt.with_timezone(&tz).fixed_offset(); - self.push(Value::DateTime(dt, offset)); + self.push(Value::DateTime(dt)); } } } @@ -871,14 +868,7 @@ impl Vm { Value::Quantity(q) => q.to_string(), Value::Boolean(b) => b.to_string(), Value::String(s) => s, - Value::DateTime(dt, offset) => { - let l: chrono::DateTime = - chrono::DateTime::from_naive_utc_and_offset( - dt.naive_utc(), - offset, - ); - l.to_rfc2822() - } + Value::DateTime(dt) => dt.to_rfc2822(), Value::FunctionReference(r) => r.to_string(), }; joined = part + &joined; // reverse order