waltzofpearls / dateparser

Parse dates in commonly used string formats with Rust.
MIT License
41 stars 8 forks source link

Default time for incomplete datetime strings #20

Closed nheitz closed 2 years ago

nheitz commented 2 years ago

QUERY: I'm quite keen to use this library, as I try to migrate from Scala/JVM world to Rust where I can. One of the better (though now really obsolete) libraries in the JVM ecosystem is the Joda datetime handler. What is tripping me up is subtle differences in handling parse for "datetimes" that only contain the date part. For example in scala:

scala> import org.joda.time.DateTime

 DateTime.parse("2021-12-02")
import org.joda.time.DateTime

scala> 
scala> res0: org.joda.time.DateTime = 2021-12-02T00:00:00.000Z

whereas in your dateparser, the same kind of parse would yield

[src/main.rs:161] date1 = 2021-12-02T12:06:22.907945488Z

Looking at the code, I can see that you are using current time as "filler" for those fields that are missing. This seems like a perfectly valid approach, but I'm wondering if you would consider extending the API to support passing arbitrary DateTime values to be used as fillier. That would allow me to replicate the behaviour of Joda a little more easily, without having to do a lot of regex parsing and date truncation in my own code.

waltzofpearls commented 2 years ago

Yes. I think parse_with function will help you do that.

Below is an example showing you how to pass a default time to the function call. To replicate what Joda does, you can call dateparser::parse_with("2021-12-02", &chrono::offset::Utc, chrono::naive::NaiveTime::from_hms(0, 0, 0))?, and it should return 2021-12-02T00:00:00Z as type chrono::DateTime<chrono::offset::Utc>.

use chrono::{
    naive::NaiveTime,
    offset::{Local, Utc},
};
use dateparser::parse_with;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let parsed_in_local = parse_with("2021-10-09", &Local, NaiveTime::from_hms(0, 0, 0))?;
    println!("{:#?}", parsed_in_local);

    let parsed_in_utc = parse_with("2021-10-09", &Utc, NaiveTime::from_hms(0, 0, 0))?;
    println!("{:#?}", parsed_in_utc);

    Ok(())
}

Since that example is in the repo, you can run it with cargo run --example parse_with.

For future v1 release, I'm going to make 00:00:00Z as default time for parse function, so it will be aligned with date parser libraries from other languages.

nheitz commented 2 years ago

Brilliant. How nice when the API already caters for the need at hand! I appreciate your response...I was in despair with the rigidity of the base chrono offerings before I discovered this library.

waltzofpearls commented 2 years ago

I couldn't agree more. I struggled when writing this library with chrono's docs, as it only has examples for common use cases. I had to read chrono source code to figure out how to made it doing things I wanted.

I will leave this issue open for 24 hours in case if you have further questions.