Skip to content

Commit

Permalink
Error if there are too many fields for NaiveDate
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed May 28, 2023
1 parent 3448efd commit 4c6f0a7
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
22 changes: 14 additions & 8 deletions src/format/parsed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use core::convert::TryFrom;

use super::{ParseResult, IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE};
use super::{ParseResult, BAD_FORMAT, IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE};
use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime};
use crate::offset::{FixedOffset, LocalResult, Offset, TimeZone};
use crate::oldtime::Duration as OldDuration;
Expand Down Expand Up @@ -286,6 +286,15 @@ impl Parsed {
set_if_consistent(&mut self.offset, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)
}

fn has_time_fields(&self) -> bool {
self.hour_div_12.is_some()
|| self.hour_mod_12.is_some()
|| self.minute.is_some()
|| self.second.is_some()
|| self.nanosecond.is_some()
|| self.timestamp.is_some()
}

/// Returns a parsed naive date out of given fields.
///
/// This method is able to determine the date from given subset of fields:
Expand All @@ -301,6 +310,9 @@ impl Parsed {
/// Gregorian year and ISO week date year can have their century number (`*_div_100`) omitted,
/// the two-digit year is used to guess the century number then.
pub fn to_naive_date(&self) -> ParseResult<NaiveDate> {
if self.has_time_fields() || self.offset.is_some() {
return Err(BAD_FORMAT);
}
self.to_naive_date_inner(true)
}

Expand Down Expand Up @@ -484,13 +496,7 @@ impl Parsed {
use_default: bool,
) -> ParseResult<NaiveDateTime> {
let date = self.to_naive_date_inner(use_default);
let time = if use_default
&& self.hour_div_12.is_none()
&& self.hour_mod_12.is_none()
&& self.minute.is_none()
&& self.second.is_none()
&& self.nanosecond.is_none()
{
let time = if use_default && !self.has_time_fields() {
Ok(NaiveTime::MIN)
} else {
self.to_naive_time_inner(use_default)
Expand Down
25 changes: 16 additions & 9 deletions src/naive/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,18 @@ impl NaiveDate {
/// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()));
/// ```
///
/// Time and offset is ignored for the purpose of parsing.
/// Time and offset will return an error, parse to a [`NaiveDateTime`] or
/// `DateTime<FixedOffset>` first.
///
/// ```
/// # use chrono::NaiveDate;
/// # let parse_from_str = NaiveDate::parse_from_str;
/// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
/// Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap()));
/// use chrono::{DateTime, FixedOffset, NaiveDate};
/// use chrono::format::ParseErrorKind;
///
/// let result = NaiveDate::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z");
/// assert_eq!(result.unwrap_err().kind(), ParseErrorKind::BadFormat);
/// let dt =
/// DateTime::<FixedOffset>::parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z");
/// assert_eq!(dt.unwrap().date_naive(), NaiveDate::from_ymd_opt(2014, 5, 17).unwrap());
/// ```
///
/// If the format string doesn't contain a day field, it defaults to the first day.
Expand Down Expand Up @@ -2963,10 +2968,6 @@ mod tests {
#[test]
fn test_date_parse_from_str() {
let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(
NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymd(2014, 5, 7))
); // ignore time and offset
assert_eq!(
NaiveDate::parse_from_str("2015-W06-1=2015-033", "%G-W%V-%u=%Y-%j"),
Ok(ymd(2015, 2, 2))
Expand All @@ -2988,6 +2989,12 @@ mod tests {
NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
NaiveDate::from_ymd_opt(2019, 1, 13),
);

assert!(NaiveDate::parse_from_str("2014-5-7T12:34:56", "%Y-%m-%dT%H:%M:%S").is_err());
assert!(NaiveDate::parse_from_str("2014-5-7+09:30", "%Y-%m-%dT%z").is_err());
assert!(
NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z").is_err()
);
}

#[test]
Expand Down

0 comments on commit 4c6f0a7

Please sign in to comment.