0

Consider the following

use chrono;


fn main() {
    println!("{:?}", chrono::NaiveDate::parse_from_str("1978-01-12 01:00:23", "%Y-%m-%d %H:%M:%S"))
}

The string contains year-month-day-hour-minute-second, but chrono only parsed year-month-day. As expected, because I used NaiveDate, not NaiveDateTime.

But is there a way to tell (programmatically) that chrono "consumed" the entire format string?

ignoring_gravity
  • 6,677
  • 4
  • 32
  • 65

3 Answers3

0

Use parse:

use chrono;


fn main() {
    let d: chrono::NaiveDate = "1978-01-12 01:00:23".parse().unwrap();
    println!("{:?}", d)
}

Result:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseError(TooLong)', src/main.rs:5:62

If you want to use parsing using formats, what stops you from checking that format doesn't contain %H, %M or %S?

0

Let's look at the implementation of parse_from_str() for:

NaiveDateTime:

pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
    let mut parsed = Parsed::new();
    parse(&mut parsed, s, StrftimeItems::new(fmt))?;
    parsed.to_naive_datetime_with_offset(0) // no offset adjustment
}

NaiveDate:

pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
    let mut parsed = Parsed::new();
    parse(&mut parsed, s, StrftimeItems::new(fmt))?;
    parsed.to_naive_date()
}

Both implementations seem identical, except for the last row. So the Parsed instance used for the NaiveDate instance is essentially the same as the one you'd have for the NaiveDateTime variant. In other words, the whole format was "consumed" the same way, but in the case of NaiveDate you've basically just used the date part of the date-time value you've parsed.

Not sure what exactly you are looking for, but I hope that info helps.

If you want to just check if you "lost" a "non-zero" time component (00:00:00) by using NaiveDate, then I guess you might just parse into a NaiveDateTime and check if its NaiveTime value is "zero".

at54321
  • 8,726
  • 26
  • 46
0

You can create a raw StrftimeItems and check if any of the items are a time component. There's a lot of variants to go through in Numeric and Fixed, but all of them seem unambiguously time or non-time.

You can check if the string has any of the time specifiers that are listed here. So %H, %k, %I, %l, etc. You would need to recreate chrono's parsing, but it's not too complex since there's only one special character, %.

You can parse a NaiveDateTime and check if the result has a nonzero time component. This doesn't really work, since the parsed time could have had 00:00:00, but maybe that's fine for you.

You can reformat the resulting NaiveDate and see if it matches the parsed time. There will be other differences that would need to be ignored, mostly in casing and padding.

drewtato
  • 6,783
  • 1
  • 12
  • 17