Use built-in duration type for durations

Previously, durations were represented as numbers counting minutes.
This commit is contained in:
Joscha 2024-12-13 21:06:39 +01:00
parent 5613173505
commit 9e4a777cf8

View file

@ -240,32 +240,28 @@
// Util // // Util //
////////// //////////
#let _pad_int(n, char: "0", width: 2) = {
let s = str(n)
for _ in array.range(width - s.clusters().len()) { char }
s
}
#let _parse_duration(s) = { #let _parse_duration(s) = {
let matched = s.match(regex("^(-?)([0-9]+):([0-5][0-9])$")) let matched = s.match(regex("^(-?)([0-9]+):([0-5][0-9])$"))
assert(matched != none, message: "invalid duration or time: " + s) assert(matched != none, message: "invalid duration or time: " + s)
let groups = matched.captures let groups = matched.captures
let sign = if groups.at(0) == "-" { -1 } else { 1 } let sign = if groups.at(0) == "-" { -1 } else { 1 }
let h = int(groups.at(1)) let hours = int(groups.at(1))
let m = int(groups.at(2)) let minutes = int(groups.at(2))
sign * (h * 60 + m) sign * duration(hours: hours, minutes: minutes)
} }
#let _fmt_duration(mins) = { #let _fmt_duration(dur) = {
if mins < 0 { if dur.seconds() < 0 {
"-" "-"
mins = -mins dur = -dur
} }
let h = int(mins / 60) let hours = calc.floor(dur.hours())
let m = mins - h * 60 let minutes = calc.rem(calc.floor(dur.minutes()), 60)
_pad_int(h, char: "0", width: 2) if hours < 10 { "0" }
str(hours)
":" ":"
_pad_int(m, char: "0", width: 2) if minutes < 10 { "0" }
str(minutes)
} }
#let _computus(year) = { #let _computus(year) = {
@ -329,7 +325,7 @@
// I think the previous two checks should make it impossible for this assert // I think the previous two checks should make it impossible for this assert
// to fail, but just to be careful... // to fail, but just to be careful...
_assert_entry(row, e, e.duration >= 0, "duration must be positive") _assert_entry(row, e, e.duration.seconds() >= 0, "duration must be positive")
// Date checks // Date checks
let date = datetime(year: year, month: month, day: e.day) let date = datetime(year: year, month: month, day: e.day)
@ -357,7 +353,7 @@
let by_day = (:) let by_day = (:)
for entry in entries { for entry in entries {
let key = str(entry.day) let key = str(entry.day)
let info = by_day.at(key, default: (duration: 0, rest: 0)) let info = by_day.at(key, default: (duration: duration(), rest: duration()))
info.duration += entry.duration info.duration += entry.duration
info.rest += entry.rest info.rest += entry.rest
by_day.insert(key, info) by_day.insert(key, info)
@ -486,9 +482,9 @@
entries = entries.sorted(key: entry => (entry.day, entry.end, entry.start)) entries = entries.sorted(key: entry => (entry.day, entry.end, entry.start))
} }
let monthly = monthly_hours * 60 let monthly = duration(hours: monthly_hours)
let holiday = entries.filter(e => e.note == notes.Urlaub).map(e => e.duration).sum(default: 0) let holiday = entries.filter(e => e.note == notes.Urlaub).map(e => e.duration).sum(default: 0)
let total = entries.map(e => e.duration).sum(default: 0) let total = entries.map(e => e.duration).sum(default: duration())
let carry_next_month = carry_prev_month + total - monthly let carry_next_month = carry_prev_month + total - monthly
if validate { if validate {