attotime/parse/
julian_date.rs1use core::str::FromStr;
4
5use crate::{JulianDate, Month, errors::JulianDateParsingError};
6
7impl FromStr for JulianDate {
8 type Err = JulianDateParsingError;
9
10 fn from_str(string: &str) -> Result<Self, Self::Err> {
14 let (date, remainder) = Self::parse_partial(string)?;
15 if !remainder.is_empty() {
16 Err(JulianDateParsingError::UnexpectedRemainder)
17 } else {
18 Ok(date)
19 }
20 }
21}
22
23impl JulianDate {
24 pub fn parse_partial(mut string: &str) -> Result<(Self, &str), JulianDateParsingError> {
32 let (year, consumed_bytes) = lexical_core::parse_partial(string.as_bytes())?;
34 string = string.get(consumed_bytes..).unwrap();
35
36 if string.starts_with('-') {
38 string = string.get(1..).unwrap();
39 } else {
40 return Err(JulianDateParsingError::ExpectedYearMonthDelimiter);
41 }
42
43 let (month, consumed_bytes) = lexical_core::parse_partial(string.as_bytes())?;
44 if consumed_bytes != 2 {
45 return Err(JulianDateParsingError::MonthRepresentationNotTwoDigits);
46 }
47 let month = Month::try_from(month)?;
48 string = string.get(consumed_bytes..).unwrap();
49
50 if string.starts_with('-') {
52 string = string.get(1..).unwrap();
53 } else {
54 return Err(JulianDateParsingError::ExpectedMonthDayDelimiter);
55 }
56
57 let (day, consumed_bytes) = lexical_core::parse_partial(string.as_bytes())?;
59 if consumed_bytes != 2 {
60 return Err(JulianDateParsingError::DayRepresentationNotTwoDigits);
61 }
62 string = string.get(consumed_bytes..).unwrap();
63
64 Ok((JulianDate::new(year, month, day)?, string))
65 }
66}
67
68#[cfg(test)]
71fn parse_known_julian_date(input: &str, year: i32, month: Month, day: u8) {
72 let date = JulianDate::from_str(input).unwrap();
73 let expected_date = JulianDate::new(year, month, day).unwrap();
74 assert_eq!(date, expected_date);
75}
76
77#[test]
79fn known_dates() {
80 use crate::Month::*;
81 parse_known_julian_date("2000-01-01", 2000, January, 1);
82 parse_known_julian_date("1999-01-01", 1999, January, 1);
83 parse_known_julian_date("1987-06-19", 1987, June, 19);
84 parse_known_julian_date("1988-01-27", 1988, January, 27);
85 parse_known_julian_date("1988-06-19", 1988, June, 19);
86 parse_known_julian_date("1900-01-01", 1900, January, 1);
87 parse_known_julian_date("1600-01-01", 1600, January, 1);
88 parse_known_julian_date("1600-12-31", 1600, December, 31);
89 parse_known_julian_date("837-04-10", 837, April, 10);
90 parse_known_julian_date("-123-12-31", -123, December, 31);
91 parse_known_julian_date("-122-01-01", -122, January, 1);
92 parse_known_julian_date("-1000-07-12", -1000, July, 12);
93 parse_known_julian_date("-1000-02-29", -1000, February, 29);
94 parse_known_julian_date("-1001-08-17", -1001, August, 17);
95 parse_known_julian_date("-4712-01-01", -4712, January, 1);
96}