Search code examples
rustrust-chrono

Rust Chrono parse date String, ParseError(NotEnough) and ParseError(TooShort)


How to convert a String to a chrono::DateTime or chrono::NaiveDateTime

And what does the ParseError(NotEnough) or ParseError(TooShort) mean?


Solution

  • When converting a String into a Chrono object you have to know what parts the input format of the string has.
    The parts are: Date, Time, TimeZone
    Examples:

    The ParseError(NotEnough) shows up when there is not enough information to fill out the whole object. For example the date, time or timezone is missing.
    When the formats doesn't match the string you get a ParseError(TooShort) or ParseError(Invalid) error.

    Specification for string format e.g. "%Y-%m-%d %H:%M:%S": https://docs.rs/chrono/latest/chrono/format/strftime/index.html

    RFC2822 = Date + Time + TimeZone

    To convert a RFC2822 string use the parse_from_rfc2822(..) function.

    let date_str = "Tue, 1 Jul 2003 10:52:37 +0200";
    let datetime = DateTime::parse_from_rfc2822(date_str).unwrap();
    

    RFC3339 = Date + Time + TimeZone

    To convert a RFC3339 or ISO 8601 string use the parse_from_rfc3339(..) function.

    let date_str = "2020-04-12T22:10:57+02:00";
    // convert the string into DateTime<FixedOffset>
    let datetime = DateTime::parse_from_rfc3339(date_str).unwrap();
    // convert the string into DateTime<Utc> or other timezone
    let datetime_utc = datetime.with_timezone(&Utc);
    

    Date + Time + Timezone (other or non-standard)

    To convert other DateTime strings use the parse_from_str(..) function.

    let date_str = "2020-04-12 22:10:57 +02:00";
    let datetime = DateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S %z").unwrap();
    

    Date + Time

    When you do not have a TimeZone you need to use NaiveDateTime. This object does not store a timezone:

    let date_str = "2020-04-12 22:10:57";
    let naive_datetime = NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S").unwrap();
    

    Date

    If we were parsing a date (with no time) we can store it in a NaiveDate. This object does not store time or a timezone:

    let date_str = "2020-04-12";
    let naive_date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d").unwrap();
    

    Time

    If we were parsing a time (with no date) we can store it in a NaiveTime. This object does not store a date or a timezone:

    let time_str = "22:10:57";
    let naive_time = NaiveTime::parse_from_str(time_str, "%H:%M:%S").unwrap();
    

    Add Date, Time and/or Timezone

    If we have some string and want to add more information we can change the type. But you have to provide this information yourself.

    let date_str = "2020-04-12";
    // From string to a NaiveDate
    let naive_date = NaiveDate::parse_from_str(date_str, "%Y-%m-%d").unwrap();
    // Add some default time to convert it into a NaiveDateTime
    let naive_datetime: NaiveDateTime = naive_date.and_hms(0,0,0);
    // Add a timezone to the object to convert it into a DateTime<UTC>
    let datetime_utc = DateTime::<Utc>::from_utc(naive_datetime, Utc);
    

    Example code playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d2b83b3980a5f8fb2e798271766b4541