time parser struct
This commit is contained in:
@ -3,16 +3,38 @@ use std::time::{
|
||||
UNIX_EPOCH,
|
||||
};
|
||||
|
||||
use std::fmt::{
|
||||
Formatter,
|
||||
Display,
|
||||
Result as FmtResult,
|
||||
};
|
||||
|
||||
use chrono_tz::Tz;
|
||||
use chrono::offset::Utc;
|
||||
use chrono::{Timelike, Datelike, TimeZone};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InvalidTime {
|
||||
ParseErrorDMY,
|
||||
ParseErrorHMS,
|
||||
ParseErrorDisplacement,
|
||||
ParseErrorChrono,
|
||||
}
|
||||
|
||||
impl Display for InvalidTime {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "InvalidTime: {:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for InvalidTime {}
|
||||
|
||||
enum ParseType {
|
||||
Explicit,
|
||||
Displacement,
|
||||
}
|
||||
|
||||
struct TimeParser {
|
||||
pub struct TimeParser {
|
||||
timezone: Tz,
|
||||
inverted: bool,
|
||||
time_string: String,
|
||||
@ -43,19 +65,10 @@ impl TimeParser {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn timestamp(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn displacement(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn process(&self) -> i32 {
|
||||
pub fn timestamp(&self) -> Result<i64, InvalidTime> {
|
||||
match self.parse_type {
|
||||
ParseType::Explicit => {
|
||||
// TODO remove unwrap from here
|
||||
self.process_explicit().unwrap()
|
||||
Ok(self.process_explicit()?)
|
||||
},
|
||||
|
||||
ParseType::Displacement => {
|
||||
@ -64,45 +77,88 @@ impl TimeParser {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time calculated as going backwards. Very bad");
|
||||
|
||||
since_epoch.as_secs() as i32 + self.process_displacement()
|
||||
Ok(since_epoch.as_secs() as i64 + self.process_displacement()?)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn process_explicit(&self) -> Result<i32, Box<dyn std::error::Error>> {
|
||||
let dt = self.timezone.datetime_from_str(self.time_string.as_str(), "%d/%m/%Y-%H:%M:%S")?;
|
||||
pub fn displacement(&self) -> Result<i64, InvalidTime> {
|
||||
match self.parse_type {
|
||||
ParseType::Explicit => {
|
||||
let now = SystemTime::now();
|
||||
let since_epoch = now
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time calculated as going backwards. Very bad");
|
||||
|
||||
Ok(dt.timestamp() as i32)
|
||||
Ok(self.process_explicit()? - since_epoch.as_secs() as i64)
|
||||
},
|
||||
|
||||
ParseType::Displacement => {
|
||||
Ok(self.process_displacement()?)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn process_displacement(&self) -> i32 {
|
||||
|
||||
fn process_explicit(&self) -> Result<i64, InvalidTime> {
|
||||
let segments = self.time_string.matches("-").count();
|
||||
|
||||
let parse_string = if segments == 1 {
|
||||
let slashes = self.time_string.matches("/").count();
|
||||
|
||||
match slashes {
|
||||
0 => Ok("%d-".to_string()),
|
||||
1 => Ok("%d/%m-".to_string()),
|
||||
2 => Ok("%d/%m/%Y-".to_string()),
|
||||
_ => Err(InvalidTime::ParseErrorDMY)
|
||||
}
|
||||
} else {
|
||||
Ok("".to_string())
|
||||
}? + if segments == 1 {
|
||||
let colons = self.time_string.matches(":").count();
|
||||
|
||||
match colons {
|
||||
1 => Ok("%H:%M"),
|
||||
2 => Ok("%H:%M:%S"),
|
||||
_ => Err(InvalidTime::ParseErrorHMS)
|
||||
}
|
||||
} else {
|
||||
Ok("")
|
||||
}?;
|
||||
|
||||
let dt = self.timezone.datetime_from_str(self.time_string.as_str(), &parse_string).map_err(|_| InvalidTime::ParseErrorChrono)?;
|
||||
|
||||
Ok(dt.timestamp() as i64)
|
||||
}
|
||||
|
||||
fn process_displacement(&self) -> Result<i64, InvalidTime> {
|
||||
let mut current_buffer = "0".to_string();
|
||||
|
||||
let mut seconds = 0 as i32;
|
||||
let mut minutes = 0 as i32;
|
||||
let mut hours = 0 as i32;
|
||||
let mut days = 0 as i32;
|
||||
let mut seconds = 0 as i64;
|
||||
let mut minutes = 0 as i64;
|
||||
let mut hours = 0 as i64;
|
||||
let mut days = 0 as i64;
|
||||
|
||||
for character in self.time_string.chars() {
|
||||
match character {
|
||||
|
||||
's' => {
|
||||
seconds = current_buffer.parse::<i32>().unwrap();
|
||||
seconds = current_buffer.parse::<i64>().unwrap();
|
||||
current_buffer = String::from("0");
|
||||
},
|
||||
|
||||
'm' => {
|
||||
minutes = current_buffer.parse::<i32>().unwrap();
|
||||
minutes = current_buffer.parse::<i64>().unwrap();
|
||||
current_buffer = String::from("0");
|
||||
},
|
||||
|
||||
'h' => {
|
||||
hours = current_buffer.parse::<i32>().unwrap();
|
||||
hours = current_buffer.parse::<i64>().unwrap();
|
||||
current_buffer = String::from("0");
|
||||
},
|
||||
|
||||
'd' => {
|
||||
days = current_buffer.parse::<i32>().unwrap();
|
||||
days = current_buffer.parse::<i64>().unwrap();
|
||||
current_buffer = String::from("0");
|
||||
},
|
||||
|
||||
@ -111,15 +167,15 @@ impl TimeParser {
|
||||
current_buffer += &c.to_string();
|
||||
}
|
||||
else {
|
||||
// raise exception
|
||||
return Err(InvalidTime::ParseErrorDisplacement)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let full = seconds + (minutes * 60) + (hours * 3600) + (days * 86400) + current_buffer.parse::<i32>().unwrap() *
|
||||
let full = seconds + (minutes * 60) + (hours * 3600) + (days * 86400) + current_buffer.parse::<i64>().unwrap() *
|
||||
if self.inverted { -1 } else { 1 };
|
||||
|
||||
full
|
||||
Ok(full)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user