Merge pull request #586 from MarekSpodBiedry:issue-578
This commit is contained in:
commit
ca9b3fbbe8
|
|
@ -59,6 +59,14 @@ pub fn serial_from_unix_ms(ms: f64) -> f64 {
|
||||||
25569.0 + ms / 86_400_000.0
|
25569.0 + ms / 86_400_000.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a 1900-system serial (as the clock supplies it) to the serial of the same instant in `sys`.
|
||||||
|
pub fn serial_in_system(sys: DateSystem, serial_1900: f64) -> f64 {
|
||||||
|
match sys {
|
||||||
|
DateSystem::D1900 => serial_1900,
|
||||||
|
DateSystem::D1904 => serial_1900 - 1462.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn civil_from_days(z: i64) -> (i32, u32, u32) {
|
pub fn civil_from_days(z: i64) -> (i32, u32, u32) {
|
||||||
let z = z + 719468;
|
let z = z + 719468;
|
||||||
let era = if z >= 0 { z } else { z - 146096 } / 146097;
|
let era = if z >= 0 { z } else { z - 146096 } / 146097;
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ impl CfCache {
|
||||||
},
|
},
|
||||||
CfRule::TimePeriod { period, style } => match v.as_f64() {
|
CfRule::TimePeriod { period, style } => match v.as_f64() {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
let today = gridcraft_calc::now_serial().floor();
|
let today = gridcraft_core::date::serial_in_system(wb.date_system, gridcraft_calc::now_serial()).floor();
|
||||||
let d = n.floor();
|
let d = n.floor();
|
||||||
let wd = gridcraft_core::date::datetime_from_serial(wb.date_system, today).map(|x| x.weekday as f64).unwrap_or(0.0);
|
let wd = gridcraft_core::date::datetime_from_serial(wb.date_system, today).map(|x| x.weekday as f64).unwrap_or(0.0);
|
||||||
let week_start = today - wd;
|
let week_start = today - wd;
|
||||||
|
|
|
||||||
|
|
@ -391,7 +391,7 @@ pub struct HfContext {
|
||||||
|
|
||||||
/// Today's date and the current time as headers and footers show them (`&D`, `&T`).
|
/// Today's date and the current time as headers and footers show them (`&D`, `&T`).
|
||||||
pub fn hf_date_time(wb: &Workbook) -> (String, String) {
|
pub fn hf_date_time(wb: &Workbook) -> (String, String) {
|
||||||
let now = gridcraft_calc::now_serial();
|
let now = gridcraft_core::date::serial_in_system(wb.date_system, gridcraft_calc::now_serial());
|
||||||
let date = crate::display::format(&Value::Number(now.floor()), "m/d/yyyy", wb).text;
|
let date = crate::display::format(&Value::Number(now.floor()), "m/d/yyyy", wb).text;
|
||||||
let time = crate::display::format(&Value::Number(now), "h:mm AM/PM", wb).text;
|
let time = crate::display::format(&Value::Number(now), "h:mm AM/PM", wb).text;
|
||||||
(date, time)
|
(date, time)
|
||||||
|
|
@ -1765,6 +1765,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn header_footer_date_follows_the_workbook_date_system() {
|
||||||
|
let mut wb = Workbook::new();
|
||||||
|
let date_1900 = hf_date_time(&wb).0;
|
||||||
|
wb.date_system = gridcraft_core::DateSystem::D1904;
|
||||||
|
assert_eq!(hf_date_time(&wb).0, date_1900);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn header_footer_section_edits_are_undoable_and_views_are_per_sheet() {
|
fn header_footer_section_edits_are_undoable_and_views_are_per_sheet() {
|
||||||
let mut s = s();
|
let mut s = s();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! Date and time functions.
|
//! Date and time functions.
|
||||||
|
|
||||||
use gridcraft_core::date::{DateTime, datetime_from_serial, days_in_month, days_in_month_in, is_leap, serial_from_ymd};
|
use gridcraft_core::date::{DateTime, datetime_from_serial, days_in_month, days_in_month_in, is_leap, serial_from_ymd, serial_in_system};
|
||||||
use gridcraft_core::parse::parse_input;
|
use gridcraft_core::parse::parse_input;
|
||||||
use gridcraft_core::{CellError, DateSystem, Value};
|
use gridcraft_core::{CellError, DateSystem, Value};
|
||||||
|
|
||||||
|
|
@ -98,10 +98,10 @@ fn second(a: &[Arg], _c: &mut dyn Ctx) -> R<Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn now(_a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
fn now(_a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
||||||
num_val(c.now_serial())
|
num_val(serial_in_system(c.date_system(), c.now_serial()))
|
||||||
}
|
}
|
||||||
fn today(_a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
fn today(_a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
||||||
num_val(c.now_serial().floor())
|
num_val(serial_in_system(c.date_system(), c.now_serial()).floor())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weekday(a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
fn weekday(a: &[Arg], c: &mut dyn Ctx) -> R<Value> {
|
||||||
|
|
@ -794,6 +794,11 @@ mod tests {
|
||||||
close(crate::call(spec, &[n(0.0)], &mut ctx), 6.0);
|
close(crate::call(spec, &[n(0.0)], &mut ctx), 6.0);
|
||||||
let spec = crate::lookup("YEAR").unwrap();
|
let spec = crate::lookup("YEAR").unwrap();
|
||||||
close(crate::call(spec, &[n(0.0)], &mut ctx), 1904.0);
|
close(crate::call(spec, &[n(0.0)], &mut ctx), 1904.0);
|
||||||
|
// The clock is 2026-10-07 12:00; in the 1904 system that is serial 44840.5.
|
||||||
|
close(crate::call(crate::lookup("NOW").unwrap(), &[], &mut ctx), 44840.5);
|
||||||
|
let today = crate::call(crate::lookup("TODAY").unwrap(), &[], &mut ctx);
|
||||||
|
close(today.clone(), 44840.0);
|
||||||
|
close(crate::call(spec, &[crate::Arg::val(today)], &mut ctx), 2026.0);
|
||||||
// No fictitious day here: 1904 is a real leap year and 1900 is before the epoch.
|
// No fictitious day here: 1904 is a real leap year and 1900 is before the epoch.
|
||||||
let spec = crate::lookup("DATE").unwrap();
|
let spec = crate::lookup("DATE").unwrap();
|
||||||
close(crate::call(spec, &[n(1904.0), n(2.0), n(29.0)], &mut ctx), 59.0);
|
close(crate::call(spec, &[n(1904.0), n(2.0), n(29.0)], &mut ctx), 59.0);
|
||||||
|
|
|
||||||
|
|
@ -179,12 +179,14 @@ pub(crate) fn dispatch(app: &mut SheetApp, ctx: &egui::Context, key: Key, physic
|
||||||
}
|
}
|
||||||
Shortcut::Dialog(name, params) => app.open_dialog(name, params),
|
Shortcut::Dialog(name, params) => app.open_dialog(name, params),
|
||||||
Shortcut::Date | Shortcut::Time => {
|
Shortcut::Date | Shortcut::Time => {
|
||||||
let now = gridcraft_engine::calc::now_serial();
|
|
||||||
let (value, format) = if shortcut == Shortcut::Date { (now.floor(), "m/d/yyyy") } else { (now.fract(), "h:mm AM/PM") };
|
|
||||||
let text = app
|
let text = app
|
||||||
.session
|
.session
|
||||||
.active()
|
.active()
|
||||||
.map(|d| gridcraft_engine::display::format(&gridcraft_engine::core::Value::Number(value), format, &d.wb).text)
|
.map(|d| {
|
||||||
|
let now = gridcraft_engine::core::date::serial_in_system(d.wb.date_system, gridcraft_engine::calc::now_serial());
|
||||||
|
let (value, format) = if shortcut == Shortcut::Date { (now.floor(), "m/d/yyyy") } else { (now.fract(), "h:mm AM/PM") };
|
||||||
|
gridcraft_engine::display::format(&gridcraft_engine::core::Value::Number(value), format, &d.wb).text
|
||||||
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
edit_with(app, text);
|
edit_with(app, text);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2458,11 +2458,13 @@ pub fn shortcut(app: &mut SheetApp, key: Key, m: Modifiers) {
|
||||||
}
|
}
|
||||||
Key::Semicolon => {
|
Key::Semicolon => {
|
||||||
// Insert today's date.
|
// Insert today's date.
|
||||||
let today = gridcraft_engine::calc::now_serial().floor();
|
|
||||||
let text = app
|
let text = app
|
||||||
.session
|
.session
|
||||||
.active()
|
.active()
|
||||||
.map(|d| gridcraft_engine::display::format(&gridcraft_engine::core::Value::Number(today), "m/d/yyyy", &d.wb).text)
|
.map(|d| {
|
||||||
|
let today = gridcraft_engine::core::date::serial_in_system(d.wb.date_system, gridcraft_engine::calc::now_serial()).floor();
|
||||||
|
gridcraft_engine::display::format(&gridcraft_engine::core::Value::Number(today), "m/d/yyyy", &d.wb).text
|
||||||
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
app.begin_edit(Some(text), false);
|
app.begin_edit(Some(text), false);
|
||||||
None
|
None
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue