EinsatzOnline/src/modules/api/personnel_billing/calculation.rs

55 lines
1.7 KiB
Rust

use chrono::Utc;
pub fn calculate_hours(real_start_time: chrono::DateTime<Utc>, real_end_time: chrono::DateTime<Utc>) -> Option<i32> {
let timestamp_start = real_start_time.timestamp() as f64;
let timestamp_end = real_end_time.timestamp() as f64;
if timestamp_start == timestamp_end {
return Some(0);
}
let hours_since_start = (timestamp_start / 3600.0);
let hours_since_end = (timestamp_end / 3600.0);
if hours_since_start > hours_since_end {
error!("real_start_time is after real_end_time");
None
} else {
Some((hours_since_end - hours_since_start).ceil() as i32)
}
}
#[cfg(test)]
mod tests {
use chrono::{TimeZone, Utc};
use crate::modules::api::personnel_billing::calculation::calculate_hours;
#[test]
fn start_after_end() {
let start = Utc.ymd(2022, 2, 2).and_hms_milli(0, 0, 1, 444);
let end = Utc.ymd(2022, 1, 1).and_hms_milli(0, 0, 1, 444);
assert!(calculate_hours(start, end).is_none())
}
#[test]
fn start_eq_end() {
let start = Utc.ymd(2022, 2, 2).and_hms_milli(0, 0, 1, 444);
let end = Utc.ymd(2022, 2, 2).and_hms_milli(0, 0, 1, 444);
assert_eq!(0, calculate_hours(start, end).unwrap())
}
#[test]
fn minutes_eq() {
let start = Utc.ymd(2022, 2, 2).and_hms_milli(14, 15, 1, 444);
let end = Utc.ymd(2022, 2, 2).and_hms_milli(16, 15, 1, 444);
assert_eq!(2, calculate_hours(start, end).unwrap())
}
#[test]
fn not_full_hour() {
let start = Utc.ymd(2022, 2, 2).and_hms_milli(14, 15, 1, 444);
let end = Utc.ymd(2022, 2, 2).and_hms_milli(14, 45, 1, 444);
assert_eq!(1, calculate_hours(start, end).unwrap())
}
}