1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use chrono::prelude::*; const PARSING_ERROR: &str = "Invalid time. Use format [hh:mm]."; const SECONDS_PER_DAY: u32 = 24 * 60 * 60; pub struct Time { pub hours: u8, pub minutes: u8, } impl Time { pub fn from(time: &str) -> Result<Time, String> { let parts: Vec<&str> = time.split(":").collect(); if parts.len() != 2 { return Err(String::from(PARSING_ERROR)) } let hours = parse_u8(parts[0])?; let minutes = parse_u8(parts[1])?; let bounds_hours = hours < 24; let bounds_minutes = minutes < 60; if !bounds_hours || !bounds_minutes { return Err(String::from(PARSING_ERROR)) } let time = Time { hours, minutes, }; Ok(time) } pub fn current() -> Time { let local: DateTime<Local> = Local::now(); Time {hours: local.hour() as u8, minutes: local.minute() as u8} } pub fn secs(&self) -> u32 { (self.hours as u32 * 60 + self.minutes as u32) * 60 } pub fn percent(&self) -> f32 { self.secs() as f32 / SECONDS_PER_DAY as f32 } pub fn percent_str(&self) -> String { let percent = self.percent() * 100.0; format!("{:.2}%", percent) } } fn parse_u8(num: &str) -> Result<u8, String> { if let Ok(num) = num.parse::<u8>() { Ok(num) } else { Err(String::from(PARSING_ERROR)) } }