Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 967
Ralph Bisschops Avatar asked Apr 12 '20 22:04

Ralph Bisschops


1 Answers

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:

  • "2020-04-12" => Date = NaiveDate
  • "22:10" => Time = NaiveTime
  • "2020-04-12 22:10:57" => Date + Time = NaiveDateTime
  • "2020-04-12 22:10:57+02:00" => Date + Time + TimeZone = DateTime<Tz>

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 where 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 where 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

like image 106
Ralph Bisschops Avatar answered Sep 21 '22 13:09

Ralph Bisschops