chrono icon indicating copy to clipboard operation
chrono copied to clipboard

Why does `from_timestamp` panic for very small values if `i64` like `i64::MIN`?

Open thomaseizinger opened this issue 5 years ago • 8 comments

We are using proptest to generate arbitrary timestamps and we have to limit the actual inputs that are generated to u32 for this function to not panic.

~Any reason why negative values are allowed here?~

thomaseizinger avatar Jun 05 '20 00:06 thomaseizinger

I was going to ask the same thing for DateTime::timestamp and Datetime::timestamp_millis but I realised it just allows to use dates before 1970-01-01.

Using

println!("{:?}", chrono::NaiveDateTime::from_timestamp(-1, 0));

gives 1969-12-31T23:59:59.

The thing I don't understand (maybe that was your real question) is why does

println!("{:?}", chrono::NaiveDateTime::from_timestamp(i64::MIN, 0));

panics ? How can a number of seconds be "out-of-range" ?

I can read in https://docs.rs/chrono/0.4.18/chrono/naive/struct.NaiveDate.html that it Allows for every proleptic Gregorian date from Jan 1, 262145 BCE to Dec 31, 262143 CE but I don't get why it couldn't handle an anterior date ?

pgimalac avatar Sep 28 '20 23:09 pgimalac

Historical dates prior to the unix epoch make sense.

I guess the decision to use an i64 is then a combination of:

  1. Avoiding the Y2k38 problem and hence any 32-bit integer is out
  2. Wanting to represent historical dates prior to the unix epoch and hence all unsigned integers are out

How can a number of seconds be "out-of-range" ?

Maybe because it doesn't really make sense to go this far back in the Gregorian calendar system? It is still unfortunate that this function panics in that case.

thomaseizinger avatar Sep 29 '20 01:09 thomaseizinger

Maybe because it doesn't really make sense to go this far back in the Gregorian calendar system?

I understand that but I don't see why the API should limit that if it's technically possible (if you can give i64::MIN and that can be treated as any other date why panic ?)

pgimalac avatar Sep 29 '20 06:09 pgimalac

Maybe because it doesn't really make sense to go this far back in the Gregorian calendar system?

I understand that but I don't see why the API should limit that if it's technically possible (if you can give i64::MIN and that can be treated as any other date why panic ?)

I think we've come to the bottom of the actual issue here so I will update the title!

thomaseizinger avatar Sep 29 '20 07:09 thomaseizinger

I think this is a great question. In the meantime, it would be good know what is the minimum valid value that won't cause my program to crash? :)

shonfeder avatar Feb 12 '21 16:02 shonfeder

u32 makes impossible to handle pre-epoch date from_timestamp(secs: i64, nsecs: u32). In order to avoid panic you have to set nsecs 0 if negative :(

NaokoReeves-BO avatar Sep 22 '21 21:09 NaokoReeves-BO

@NaokoReeves-BO I think since nsecs is a number of nanoseconds, it's supposed to be between 0 and 1,000,000,000 (although it could be more because of the leap second issue). It doesn't make sense to have a negative amount of ns, you can just lower the number of seconds to balance it...

https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDateTime.html#method.from_timestamp

pgimalac avatar Sep 22 '21 21:09 pgimalac

@pgimalac that make sense. thank you very much!

NaokoReeves-BO avatar Sep 22 '21 22:09 NaokoReeves-BO

An i64 Unix timestamp can cover a wider range of dates than a NaiveDateTime or DateTime. Although with a range of +/-260,000 years it already seems pretty generous.

To avoid a panic when converting from a timestamp, use the from_timestamp_opt method.

pitdicker avatar Jun 07 '23 08:06 pitdicker