Operations/Comparisons between Dates

Hi.
I am working with dates in Rust but it seems that there isn't a way to compare or make operations between date. Does anyone know how could I work things like: "check if someone is between X and Y age using Date (NaiveDate)"

Thank you for the help!

Code:
fechaaux is a conversion from a tring that gives an "older date" Ex: 1994-01-10
and fechaaux2 is a conversion from todays date.

let fechaaux1 =  NaiveDate::parse_from_str(&fecha.to_string(), "%Y-%m-%d");
let fechaaux2 =  NaiveDate::parse_from_str(&fechahoy.to_string(), "%Y-%m-%d");
let b = fechaaux2 - fechaaux1;  <-- This is were I want to make operations or comparisons
if b<84
{}...
1 Like

The Sub trait implementation for chrono::naive::NaiveDate (which is what allows you to do fechaaux2 - fechaaux1) has chrono::Duration for an output type, so you probably need to construct another Duration value to compare b to, e.g. with Duration::weeks(84 * 52) (I don't know if this is actually a good way to create a duration representing 84 years; probably not).

1 Like

What is a "Sub trait implementation"?. Sorry, I am still new so I am not very familiar with some words of this language. ( ; - ; )
I tried using "Duration" with .checked_sub_signed(Duration::weeks(4)) and with checked_add_signed but I wasn't sure how could I use it as a comparison for years.

When you write

let b = fechaaux2 - fechaaux1;

what the compiler sees is this:

let b = fechaaux2.sub(fechaaux1);

where sub is a method of the trait Sub from the standard library. When you implement Sub for a type T, you tell the language how to compute x - y -- which, again, is the same thing as x.sub(y) -- when x and y are of type T. As part of implementing Sub, you specify what the output type should be, i.e. what should be the type of z after this line:

let z = x - y;

Now if you look at the documentation for the Sub implementation for NaiveDate here, you see that the output type is chrono::Duration, so when you subtract fechaaux1 from fechaaux2 you get a value of type Duration.

To be clear, here's how I'd rewrite your code:

let fechaaux1 = NaiveDate::parse_from_str(&fecha.to_string(), "%Y-%m-%d");
let fechaaux2 = NaiveDate::parse_from_str(&fechahoy.to_string(), "%Y-%m-%d");
let b = fechaaux2 - fechaaux1;
if b < Duration::weeks(84 * 52) {
    // ...
}

except that Duration::weeks(84 * 52) is probably not the ideal way to get a duration representing 84 years; I don't see a better way to do it in the chrono documentation but I could easily be missing something.

1 Like

The thing is that when I try to use the substract it doesn't let me due to this error:

cannot subtract `std::result::Result<chrono::NaiveDate, chrono::ParseError>` from `std::result::Result<chrono::NaiveDate, chrono::ParseError>` rustc(E0369)

I am not really sure why, 'cause I already converted first to a String and then to NaiveDate.

Oh, that's because NaiveDate::parse_from_str can fail, so it returns Result<NaiveDate, chrono::ParseError>, and if you want to get a NaiveDate value you need to handle potential errors somehow. The simplest thing would be to panic (cause the program to stop executing with an error message) using something like

let fechaaux1 = NaiveDate::parse_from_str(&fecha.to_string(), "%Y-%m-%d").unwrap();
let fechaaux2 = NaiveDate::parse_from_str(&fechahoy.to_string(), "%Y-%m-%d").unwrap();

See the documentation for more: Result, Result::unwrap. If you're not comfortable/familiar with error handling in Rust using Result and Option you will probably find this chapter in The Rust Programming Language useful.

Sorry for not catching that aspect in my previous posts.

2 Likes

Oh, I see, when I first saw "The simplest thing would be to panic" I laughed thinking: "Oh, well that is already covered".
Gonna check about the Result::unwrap in case I find another thing like this.

Thank your for your help again! :smile:

3 Likes