| @@ -1,6 +1,8 @@ |
| 1 | #[derive(thiserror::Error, Debug)] | 1 | #[derive(thiserror::Error, Debug)] |
| 2 | #[allow(missing_docs)] | 2 | #[allow(missing_docs)] |
| 3 | pub enum Error { | 3 | pub enum Error { |
| | 4 | #[error("Cannot represent times before UNIX epoch at timestamp {timestamp}")] |
| | 5 | TooEarly { timestamp: i64 }, |
| 4 | #[error("Date string can not be parsed")] | 6 | #[error("Date string can not be parsed")] |
| 5 | InvalidDateString, | 7 | InvalidDateString, |
| 6 | #[error("Dates past 2038 can not be represented.")] | 8 | #[error("Dates past 2038 can not be represented.")] |
| @@ -44,12 +46,21 @@ pub(crate) mod function { · 37 unmodified lines |
| 44 | // Format::Raw | 46 | // Format::Raw |
| 45 | val | 47 | val |
| 46 | } else if let Some(time) = relative::parse(input, now).transpose()? { | 48 | } else if let Some(time) = relative::parse(input, now).transpose()? { |
| 47 | Time::new(time.unix_timestamp().try_into()?, time.offset().whole_seconds()) | 49 | Time::new(timestamp(time)?, time.offset().whole_seconds()) |
| 48 | } else { | 50 | } else { |
| 49 | return Err(Error::InvalidDateString); | 51 | return Err(Error::InvalidDateString); |
| 50 | }) | 52 | }) |
| 51 | } | 53 | } |
| 52 | | 54 | |
| | 55 | fn timestamp(date: OffsetDateTime) -> Result<u32, Error> { |
| | 56 | let timestamp = date.unix_timestamp(); |
| | 57 | if timestamp < 0 { |
| | 58 | Err(Error::TooEarly { timestamp }) |
| | 59 | } else { |
| | 60 | Ok(timestamp.try_into()?) |
| | 61 | } |
| | 62 | } |
| | 63 | |
| 53 | fn parse_raw(input: &str) -> Option<Time> { | 64 | fn parse_raw(input: &str) -> Option<Time> { |
| 54 | let mut split = input.split_whitespace(); | 65 | let mut split = input.split_whitespace(); |
| 55 | let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?; | 66 | let seconds_since_unix_epoch: u32 = split.next()?.parse().ok()?; |