chrono icon indicating copy to clipboard operation
chrono copied to clipboard

Feature request: get absolute duration

Open alextes opened this issue 1 year ago • 2 comments

I have a stream of timestamped values, I have a function that tries to retrieve one of those values 24 hours back in time, where the value needs to be within 10 minutes, on either side, of now - hours_24. SQL has a great way to get me the row closest to a given point in time, but now I wanted to check on the rust side whether the closest value is actually within our time limit.

The code ends up looking like this:

let h24_ago = Utc::now() - Duration::hours(24);
let secs_between = (h24_ago - eth_price.timestamp).num_seconds().abs();
let is_fresh_enough = Duration::seconds(secs_between) <= age_limit;

I was already quite happy to find negative Duration is perfectly acceptable but I still need to jump through some hoops because it is nice for age_limit to be a Duration rather than a number of seconds or something.

Now that I write this I'm thinking maybe I should just go through the trouble of writing the WHERE in SQL but either way I'll leave this here, perhaps others need it too, and after a couple of 👍 we could consider implementing ((:

alextes avatar Sep 02 '22 18:09 alextes

Mya, as sqlx has no clue how to put a Duration into SQL it ends up being more lines for me I think because now I need to bind the age_limit into the query. Still, its neater to have it in there I think.

alextes avatar Sep 02 '22 18:09 alextes

This is likely to be implemented in https://github.com/chronotope/chrono/pull/714 - see chrono::TimeDelta::abs.

esheppa avatar Sep 03 '22 02:09 esheppa

The Duration type of chrono has an abs method since https://github.com/chronotope/chrono/pull/418. But you get the Duration from time 0.1 which doesn't have abs if the oldtime features is enabled.

pitdicker avatar Jun 29 '23 17:06 pitdicker

@pitdicker can you elaborate? It is still not clear to me how I can get an absolute duration using the current release of chrono.

Here's a code sample that doesn't compile:

use chrono; // 0.4.26

struct EthPrice {
    usd: u32,
    timestamp: chrono::DateTime<chrono::Utc>
}

fn main() {
    let eth_price = EthPrice { usd: 2000, timestamp: chrono::Utc::now() };
    let age_limit = chrono::Duration::minutes(10);
    let h24_ago = chrono::Utc::now() - chrono::Duration::hours(24);
    let secs_between = (h24_ago - eth_price.timestamp).abs();
    let is_fresh_enough = chrono::Duration::seconds(secs_between) <= age_limit;
    dbg!(is_fresh_enough);
}

error:

error[[E0599]](https://doc.rust-lang.org/stable/error_codes/E0599.html): no method named `abs` found for struct `chrono::Duration` in the current scope
  --> src/main.rs:12:56
   |
12 |     let secs_between = (h24_ago - eth_price.timestamp).abs();
   |                                                        ^^^ method not found in `Duration`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (bin "playground") due to previous error

Perhaps at the very least we can link an issue tracking when "you get the Duration from time 0.1" is no longer the case and this feature is unlocked? If it isn't already and I am simply misunderstanding how to use it.

alextes avatar Jun 30 '23 09:06 alextes

It is available if you use chrono with:

[dependencies]
chrono = { version = "0.4.26", default-features = false, features = ["clock", "std"] }

This is unfortunate, hopefully it 'just works' in the next release when we remove the time 0.1 dependency. See https://github.com/chronotope/chrono/pull/1095.

pitdicker avatar Jun 30 '23 11:06 pitdicker