Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime Overflow in .NET

We have a Scala/Java back end that is generating the equivalent of DateTime.MaxValue in .NET.

I am sent the following date as a string "9999-12-31T23:59:59.999999999Z".

If I used DateTime.TryParse("9999-12-31T23:59:59.999999999Z", out var dateTime), then it throws an ArgumentOutOfRangeException (The added or subtracted value results in an un-representable DateTime.Parameter name: value).

I didn't expect this, since I was calling TryParse. Perhaps returning false would have been more intuitive?

If I reduce the year, I can see .NET is rolling the date over to the following day, which obviously wont work on a max date/time!

DateTime.TryParse("9998-12-31T23:59:59.999999999Z", out var dateTime);
dateTime.ToString().Dump();

Outputs: 01/01/9999 00:00:00

If I reduce the precision of the ms by 2, then it works:

DateTime.TryParse("9998-12-31T23:59:59.9999999Z", out var dateTime);
dateTime.ToString().Dump();

Outputs: 31/12/9998 23:59:59

This really looks like a bug in .NET? Is this expected behaviour?

like image 212
David Kiff Avatar asked Oct 19 '18 10:10

David Kiff


1 Answers

Passing Min/Max/Infinity and etc. values between different platforms is a bad idea. Each platform might have its own representation of special values (not only dates). Therefore the only valid option is to pass epoch values (milliseconds options are preferable in most cases), since they are known to the both parties.

If the above is impossible for some reason then you have two ugly options:

  1. Replace special values in your Scala/Java output with your own "encoding". For example as "MaxValue", or take your pick as your see fit. On the .Net side you will detect special values and translate them accordingly.

  2. Insert some simple preprocessing into your .Net code. For example check "9999-12-31T23:59:59.999999999".StartsWith("9999") for max values.

like image 92
Bennie Tamir Avatar answered Nov 09 '22 06:11

Bennie Tamir