Support "half an hour ago" time specifier

This commit is contained in:
Abraham Toriz 2021-12-13 13:58:37 -06:00
parent 9a740f817b
commit e45b1baa30
No known key found for this signature in database
GPG Key ID: D5B4A746DB5DD42A
2 changed files with 41 additions and 37 deletions

View File

@ -60,11 +60,13 @@ pub fn parse_time(input: &str) -> Result<DateTime<Utc>> {
NUMBER_VALUES[&caps["hcten"]] + NUMBER_VALUES[&caps["hcdigit"]] NUMBER_VALUES[&caps["hcten"]] + NUMBER_VALUES[&caps["hcdigit"]]
} else if let Some(m) = caps.name("htextualnum") { } else if let Some(m) = caps.name("htextualnum") {
m.as_str().parse().unwrap() m.as_str().parse().unwrap()
} else if let Some(_) = caps.name("half") {
0.5
} else { } else {
unreachable!() unreachable!()
} }
} else { } else {
0 0.
}; };
let minutes = if caps.name("minute").is_some() { let minutes = if caps.name("minute").is_some() {
@ -82,11 +84,11 @@ pub fn parse_time(input: &str) -> Result<DateTime<Utc>> {
unreachable!() unreachable!()
} }
} else { } else {
0 0.
}; };
return Ok(Utc.from_utc_datetime( return Ok(Utc.from_utc_datetime(
&(Local::now() - Duration::minutes(hours * 60 + minutes)).naive_utc() &(Local::now() - Duration::minutes((hours * 60. + minutes) as i64)).naive_utc()
)); ));
} }
@ -208,13 +210,13 @@ mod tests {
} }
fn time_diff(t1: DateTime<Utc>, t2: DateTime<Local>) { fn time_diff(t1: DateTime<Utc>, t2: DateTime<Local>) {
let diff = (t1 - dbg!(Utc.from_utc_datetime(&dbg!(t2.naive_utc())))).num_seconds(); let diff = dbg!(dbg!(t1) - dbg!(Utc.from_utc_datetime(&t2.naive_utc()))).num_seconds().abs();
assert!(diff < 1, "too different: {} s", diff); assert!(diff < 1, "too different: {} s", diff);
} }
#[test] #[test]
fn parse_human_minute() { fn parse_human_times() {
// hours // hours
time_diff(parse_time("an hour ago").unwrap(), Local::now() - Duration::hours(1)); time_diff(parse_time("an hour ago").unwrap(), Local::now() - Duration::hours(1));
time_diff(parse_time("two hours ago").unwrap(), Local::now() - Duration::hours(2)); time_diff(parse_time("two hours ago").unwrap(), Local::now() - Duration::hours(2));
@ -229,10 +231,11 @@ mod tests {
time_diff(parse_time("forty one minutes ago").unwrap(), Local::now() - Duration::minutes(41)); time_diff(parse_time("forty one minutes ago").unwrap(), Local::now() - Duration::minutes(41));
time_diff(parse_time("1 minute ago").unwrap(), Local::now() - Duration::minutes(1)); time_diff(parse_time("1 minute ago").unwrap(), Local::now() - Duration::minutes(1));
time_diff(parse_time("23 minutes ago").unwrap(), Local::now() - Duration::minutes(23)); time_diff(parse_time("23 minutes ago").unwrap(), Local::now() - Duration::minutes(23));
time_diff(parse_time("half an hour ago").unwrap(), dbg!(Local::now() - Duration::minutes(30)));
// mixed // mixed
time_diff(parse_time("an hour 10 minutes ago").unwrap(), Local::now() - Duration::minutes(1)); time_diff(parse_time("an hour 10 minutes ago").unwrap(), Local::now() - Duration::minutes(70));
time_diff(parse_time("2 hours five minutes ago").unwrap(), Local::now() - Duration::minutes(1)); time_diff(parse_time("2 hours five minutes ago").unwrap(), Local::now() - Duration::minutes(125));
time_diff(parse_time("an hour 12 minutes ago").unwrap(), Local::now() - Duration::minutes(1 * 60 + 12)); time_diff(parse_time("an hour 12 minutes ago").unwrap(), Local::now() - Duration::minutes(1 * 60 + 12));
// abbreviated // abbreviated

View File

@ -7,6 +7,7 @@ lazy_static! {
pub static ref HUMAN_REGEX: Regex = Regex::new(r"(?xi) pub static ref HUMAN_REGEX: Regex = Regex::new(r"(?xi)
(?P<hour> (?P<hour>
(?P<hnum> (?P<hnum>
(?P<half>half(\s+)a(n)?)|
(?P<hcase>a|an|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen)| (?P<hcase>a|an|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen)|
(?P<hdigit>one|two|three|four|five|six|seven|eight|nine)| (?P<hdigit>one|two|three|four|five|six|seven|eight|nine)|
(?P<hten>ten|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety)| (?P<hten>ten|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety)|
@ -63,39 +64,39 @@ lazy_static! {
)? # the offset, optional )? # the offset, optional
").unwrap(); ").unwrap();
pub static ref NUMBER_VALUES: HashMap<&'static str, i64> = { pub static ref NUMBER_VALUES: HashMap<&'static str, f64> = {
vec![ vec![
("a", 1), ("a", 1.),
("an", 1), ("an", 1.),
("ten", 10), ("ten", 10.),
("eleven", 11), ("eleven", 11.),
("twelve", 12), ("twelve", 12.),
("thirteen", 13), ("thirteen", 13.),
("fourteen", 14), ("fourteen", 14.),
("fifteen", 15), ("fifteen", 15.),
("sixteen", 16), ("sixteen", 16.),
("seventeen", 17), ("seventeen", 17.),
("eighteen", 18), ("eighteen", 18.),
("nineteen", 19), ("nineteen", 19.),
("one", 1), ("one", 1.),
("two", 2), ("two", 2.),
("three", 3), ("three", 3.),
("four", 4), ("four", 4.),
("five", 5), ("five", 5.),
("six", 6), ("six", 6.),
("seven", 7), ("seven", 7.),
("eight", 8), ("eight", 8.),
("nine", 9), ("nine", 9.),
("twenty", 20), ("twenty", 20.),
("thirty", 30), ("thirty", 30.),
("forty", 40), ("forty", 40.),
("fifty", 50), ("fifty", 50.),
("sixty", 60), ("sixty", 60.),
("seventy", 70), ("seventy", 70.),
("eighty", 80), ("eighty", 80.),
("ninety", 90), ("ninety", 90.),
].into_iter().collect() ].into_iter().collect()
}; };
} }