|
| 1 | +use crate::time::format::{RFC2822, SHORT}; |
1 | 2 | use crate::Time;
|
| 3 | +use time::{Date, OffsetDateTime}; |
2 | 4 |
|
3 | 5 | #[allow(missing_docs)]
|
4 | 6 | pub fn parse(input: &str) -> Option<Time> {
|
5 | 7 | // TODO: actual implementation, this is just to not constantly fail
|
6 | 8 | if input == "1979-02-26 18:30:00" {
|
7 | 9 | Some(Time::new(42, 1800))
|
8 | 10 | } else {
|
9 |
| - None |
| 11 | + return if let Ok(val) = Date::parse(input, SHORT) { |
| 12 | + let val = val.with_hms(0, 0, 0).expect("date is in range").assume_utc(); |
| 13 | + Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds())) |
| 14 | + } else if let Ok(val) = OffsetDateTime::parse(input, RFC2822) { |
| 15 | + Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds())) |
| 16 | + } else if let Some(val) = relative::parse(input) { |
| 17 | + Some(Time::new(val.unix_timestamp() as u32, val.offset().whole_seconds())) |
| 18 | + } else { |
| 19 | + None |
| 20 | + }; |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +mod relative { |
| 25 | + use std::str::FromStr; |
| 26 | + use time::{Duration, OffsetDateTime}; |
| 27 | + |
| 28 | + pub(crate) fn parse(input: &str) -> Option<OffsetDateTime> { |
| 29 | + let split: Vec<&str> = input.split_whitespace().collect(); |
| 30 | + if split.len() != 3 || *split.last().expect("slice has length 3") != "ago" { |
| 31 | + return None; |
| 32 | + } |
| 33 | + let multiplier = i64::from_str(split[0]).ok()?; |
| 34 | + let period = period_to_seconds(split[1])?; |
| 35 | + Some(OffsetDateTime::now_utc().checked_sub(Duration::seconds(multiplier * period))?) |
| 36 | + } |
| 37 | + |
| 38 | + fn period_to_seconds(period: &str) -> Option<i64> { |
| 39 | + let period = period.strip_suffix("s").unwrap_or(period); |
| 40 | + return match period { |
| 41 | + "second" => Some(1), |
| 42 | + "minute" => Some(60), |
| 43 | + "hour" => Some(60 * 60), |
| 44 | + "day" => Some(24 * 60 * 60), |
| 45 | + "week" => Some(7 * 24 * 60 * 60), |
| 46 | + // TODO months & years |
| 47 | + _ => None, |
| 48 | + }; |
10 | 49 | }
|
11 | 50 | }
|
0 commit comments