55 lines
1.7 KiB
Rust
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())
|
|
}
|
|
} |