chore: switch from h-float to min-int in timesheet
Some checks failed
Release / Build and Release (push) Successful in 6s
Continuous Integration / Lint, Check & Test (push) Failing after 56s
Continuous Integration / Build Package (push) Successful in 1m42s

This commit is contained in:
Konstantin Fickel 2026-04-07 08:28:50 +02:00
parent a79111c650
commit d614d678af
Signed by: kfickel
GPG key ID: A793722F9933C1A5
3 changed files with 156 additions and 135 deletions

View file

@ -40,30 +40,28 @@ fn load_all_shards(base_folder: &Path) -> Result<Vec<LocalizedShard>, StreamdErr
Ok(shards)
}
/// Format hours with sign for display.
fn format_diff(hours: f64, use_minutes: bool) -> String {
/// Format minutes with sign for display.
fn format_diff(minutes: i64, use_minutes: bool) -> String {
let sign = if minutes >= 0 { "+" } else { "-" };
if use_minutes {
let total_minutes = (hours * 60.0).round() as i32;
let h = total_minutes.abs() / 60;
let m = total_minutes.abs() % 60;
let sign = if hours >= 0.0 { "+" } else { "-" };
let h = minutes.unsigned_abs() / 60;
let m = minutes.unsigned_abs() % 60;
format!("{}{}:{:02}", sign, h, m)
} else if hours >= 0.0 {
format!("+{:.1}h", hours.abs())
} else {
format!("{:.1}h", hours)
let hours = minutes.unsigned_abs() as f64 / 60.0;
format!("{}{:.1}h", sign, hours)
}
}
/// Format hours for display without sign.
fn format_hours(hours: f64, use_minutes: bool) -> String {
/// Format minutes for display without sign.
fn format_hours(minutes: i64, use_minutes: bool) -> String {
if use_minutes {
let total_minutes = (hours * 60.0).round() as i32;
let h = total_minutes.abs() / 60;
let m = total_minutes.abs() % 60;
let h = minutes.unsigned_abs() / 60;
let m = minutes.unsigned_abs() % 60;
format!("{}:{:02}", h, m)
} else {
format!("{:.1}h", hours.abs())
let hours = minutes.unsigned_abs() as f64 / 60.0;
format!("{:.1}h", hours)
}
}
@ -112,8 +110,8 @@ fn print_month(month: &MonthReport, use_minutes: bool) {
for day in &month.days {
let date_str = day.date.format("%Y-%m-%d").to_string();
let weekday = weekday_abbrev(day.date);
let expected = format_hours(day.expected_hours, use_minutes);
let actual = format_hours(day.actual_hours, use_minutes);
let expected = format_hours(day.expected_minutes, use_minutes);
let actual = format_hours(day.actual_minutes, use_minutes);
let diff = format_diff(day.diff(), use_minutes);
let type_str = match day.day_type {
@ -155,7 +153,7 @@ fn print_month(month: &MonthReport, use_minutes: bool) {
}
/// Print the cumulative balance.
fn print_cumulative_balance(balance: f64, use_minutes: bool) {
fn print_cumulative_balance(balance: i64, use_minutes: bool) {
let light_line = "\u{2500}".repeat(SEPARATOR_WIDTH);
println!("{}", light_line);
println!(
@ -227,11 +225,11 @@ fn print_warnings(report: &TimesheetReport, use_minutes: bool) {
if !outside_period_warnings.is_empty() {
println!(" Work logged outside configured periods:");
for w in &outside_period_warnings {
if let DayWarning::OutsidePeriod { hours_worked } = &w.warning {
if let DayWarning::OutsidePeriod { minutes_worked } = &w.warning {
println!(
" - {}: {} worked (no period configured)",
w.date.format("%Y-%m-%d"),
format_hours(*hours_worked, use_minutes)
format_hours(*minutes_worked, use_minutes)
);
}
}
@ -294,31 +292,33 @@ mod tests {
#[test]
fn test_format_hours_decimal() {
assert_eq!(format_hours(8.0, false), "8.0h");
assert_eq!(format_hours(8.5, false), "8.5h");
assert_eq!(format_hours(0.0, false), "0.0h");
assert_eq!(format_hours(480, false), "8.0h");
assert_eq!(format_hours(510, false), "8.5h");
assert_eq!(format_hours(0, false), "0.0h");
}
#[test]
fn test_format_hours_minutes() {
assert_eq!(format_hours(8.0, true), "8:00");
assert_eq!(format_hours(8.5, true), "8:30");
assert_eq!(format_hours(0.0, true), "0:00");
assert_eq!(format_hours(1.25, true), "1:15");
assert_eq!(format_hours(480, true), "8:00");
assert_eq!(format_hours(510, true), "8:30");
assert_eq!(format_hours(0, true), "0:00");
assert_eq!(format_hours(75, true), "1:15");
assert_eq!(format_hours(77, true), "1:17");
assert_eq!(format_hours(200, true), "3:20");
}
#[test]
fn test_format_diff_decimal() {
assert_eq!(format_diff(0.5, false), "+0.5h");
assert_eq!(format_diff(-1.5, false), "-1.5h");
assert_eq!(format_diff(0.0, false), "+0.0h");
assert_eq!(format_diff(30, false), "+0.5h");
assert_eq!(format_diff(-90, false), "-1.5h");
assert_eq!(format_diff(0, false), "+0.0h");
}
#[test]
fn test_format_diff_minutes() {
assert_eq!(format_diff(0.5, true), "+0:30");
assert_eq!(format_diff(-1.5, true), "-1:30");
assert_eq!(format_diff(0.0, true), "+0:00");
assert_eq!(format_diff(1.25, true), "+1:15");
assert_eq!(format_diff(30, true), "+0:30");
assert_eq!(format_diff(-90, true), "-1:30");
assert_eq!(format_diff(0, true), "+0:00");
assert_eq!(format_diff(75, true), "+1:15");
}
}