From dc407a6833b8358855fe5fb949b4253874311f47 Mon Sep 17 00:00:00 2001 From: Alan Du Date: Thu, 1 Jun 2017 20:35:39 +0100 Subject: Truncate fractional seconds to picoseconds Close https://github.com/alexcrichton/toml-rs/issues/186 --- src/datetime.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/datetime.rs') diff --git a/src/datetime.rs b/src/datetime.rs index f39d9fa..810a4d7 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -218,7 +218,10 @@ impl FromStr for Datetime { return Err(DatetimeParseError { _private: () }) } chars = whole[end..].chars(); - match format!("0.{}", &whole[..end]).parse() { + + // truncate to picoseconds precision + let last = if end > 12 { 12 } else { end }; + match format!("0.{}", &whole[..last]).parse() { Ok(f) => f, Err(_) => return Err(DatetimeParseError { _private: () }), } -- cgit v1.2.3 From 2dfc9fedd30bf3d40c4c3e97adc06fe3aad34361 Mon Sep 17 00:00:00 2001 From: Alan Du Date: Thu, 1 Jun 2017 23:22:35 +0100 Subject: Store fractional seconds as a u32 instead of a f64 Drops precision down to the nanoseconds --- src/datetime.rs | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'src/datetime.rs') diff --git a/src/datetime.rs b/src/datetime.rs index 810a4d7..83b5c0b 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -55,7 +55,7 @@ struct Time { hour: u8, minute: u8, second: u8, - secfract: f64, + nanosecond: u32, } #[derive(PartialEq, Clone)] @@ -97,9 +97,9 @@ impl fmt::Display for Date { impl fmt::Display for Time { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:02}:{:02}:{:02}", self.hour, self.minute, self.second)?; - if self.secfract != 0.0 { - let s = format!("{}", self.secfract); - write!(f, "{}", s.trim_left_matches("0"))?; + if self.nanosecond != 0 { + let s = format!("{:09}", self.nanosecond); + write!(f, ".{}", s.trim_right_matches('0'))?; } Ok(()) } @@ -199,41 +199,37 @@ impl FromStr for Datetime { let s1 = digit(&mut chars)?; let s2 = digit(&mut chars)?; - let secfract = if chars.clone().next() == Some('.') { + let mut nanosecond = 0; + if chars.clone().next() == Some('.') { chars.next(); - let mut first = true; let whole = chars.as_str(); + let mut end = whole.len(); - for (i, c) in whole.char_indices() { - match c { - '0' ... '9' => {} + for (i, byte) in whole.bytes().enumerate() { + match byte { + b'0' ... b'9' => { + if i < 9 { + let p = 10_u32.pow(8 - i as u32); + nanosecond += p * (byte - b'0') as u32; + } + } _ => { end = i; - break + break; } } - first = false; } - if first { + if end == 0 { return Err(DatetimeParseError { _private: () }) } chars = whole[end..].chars(); - - // truncate to picoseconds precision - let last = if end > 12 { 12 } else { end }; - match format!("0.{}", &whole[..last]).parse() { - Ok(f) => f, - Err(_) => return Err(DatetimeParseError { _private: () }), - } - } else { - 0.0 - }; + } let time = Time { hour: h1 * 10 + h2, minute: m1 * 10 + m2, second: s1 * 10 + s2, - secfract: secfract, + nanosecond: nanosecond, }; if time.hour > 24 { @@ -242,7 +238,10 @@ impl FromStr for Datetime { if time.minute > 59 { return Err(DatetimeParseError { _private: () }) } - if time.second > 60 { + if time.second > 59 { + return Err(DatetimeParseError { _private: () }) + } + if time.nanosecond > 999_999_999 { return Err(DatetimeParseError { _private: () }) } -- cgit v1.2.3