deep_time/time_parts/
from_str.rs1use crate::{DtErrKind, DtErr, Offset, TimeParts, an_err, parser::Parser};
2
3impl TimeParts {
4 pub fn from_str(
5 fmt: &str,
6 input: &str,
7 inp_can_end_before_fmt: bool,
8 fmt_can_end_before_inp: bool,
9 allow_partial_date: bool,
10 ) -> Result<TimeParts, DtErr> {
11 let mut tm = TimeParts::new_utc();
12 let mut parser = Parser::new(
13 fmt.as_bytes(),
14 input.as_bytes(),
15 &mut tm,
16 inp_can_end_before_fmt,
17 );
18 if let Err(e) = parser.parse() {
19 return Err(e);
20 }
21 if parser.inp.is_empty() || fmt_can_end_before_inp {
22 tm.finish(allow_partial_date)?;
24 Ok(tm)
25 } else {
26 Err(an_err!(DtErrKind::TrailingCharacters))
28 }
29 }
30
31 pub fn finish(&mut self, allow_partial_date: bool) -> core::result::Result<&mut Self, DtErr> {
32 if self.unix_timestamp_seconds.is_some() {
33 if self.hour.is_none() {
34 self.hour = Some(0);
35 }
36 if self.minute.is_none() {
37 self.minute = Some(0);
38 }
39 if self.second.is_none() {
40 self.second = Some(0);
41 }
42 if self.attos.is_none() {
43 self.attos = Some(0);
44 }
45 if self.offset.is_none() {
46 self.offset = Some(Offset::Utc);
47 }
48 return Ok(self);
49 }
50
51 if self.hour.is_none() {
53 self.hour = Some(0);
54 }
55 if self.minute.is_none() {
56 self.minute = Some(0);
57 }
58 if let Some(sec) = self.second {
59 if sec == 60 {
60 self.is_leap_second = true;
61 } else if sec > 60 {
62 return Err(an_err!(DtErrKind::OutOfRange, "seconds (0..=60): {}", sec));
63 }
64 } else {
65 self.second = Some(0);
66 }
67 if self.attos.is_none() {
68 self.attos = Some(0);
69 }
70 if self.offset.is_none() {
71 self.offset = Some(Offset::Utc);
72 }
73
74 let has_calendar_date = if allow_partial_date {
75 if self.day.is_none() {
76 self.day = Some(1);
77 }
78 if self.month.is_none() {
79 self.month = Some(1);
80 }
81 self.year.is_some()
82 } else {
83 self.year.is_some() && self.month.is_some() && self.day.is_some()
84 };
85 let has_ordinal_date = self.year.is_some() && self.day_of_year.is_some();
86 let has_iso_week_date = self.iso_week_year.is_some() && self.iso_week.is_some();
87
88 if !has_calendar_date && !has_ordinal_date && !has_iso_week_date {
89 return Err(an_err!(DtErrKind::Incomplete));
90 }
91
92 Ok(self)
93 }
94}