📜 ⬆️ ⬇️

Oh, I have these databases: Sybase (ASE) and datetime

Hi, Habr!
Actually a post about one line in the documentation, as it turned out. But it was unexpected, so I decided to share with you the found.

A new project, a new table, decided to write tests for them, and, in general, was surprised when the first test I wrote broke down on the fact that the object I threw into the database is not equal to the same object that was extracted from the database.
After re-launches, it became clear that milliseconds did not converge. Well, that is, you take such an object, say “here's a new Date () for you, and now write it in the database. And now read on the ID. And now equals. Whatooooo O_o. Something like this. And, yes, all of a sudden the test can succeed.
After some digging it turned out an interesting thing.
The documentation on the Sybase site has a description of the data types used. For the datetime data type, in the ASE version 15.0 there was only this:
if the link breaks, then Adaptive Server Enterprise 15.0> Reference Manual: Building Blocks> System and User-Defined Datatypes> Date and time datatypes , where it is said that
datetime columns hold dates between January 1, 1753 and December 31, 9999. The level of granularity. Since the date of January 1, 1900 and 4 bytes for the time of day.
Once again I draw attention to the fact that
datetime values ​​are accurate to 1/300 second
In the upper 4 bytes the days are stored, and in the lower 4 bytes the time of the day. In 24 hours of the day * 60 minutes * 60 seconds * 1000 milliseconds = 86_400_000 milliseconds per day, a number that is quite 4 bytes (0x5_26_5C_00). Even for the sign bit there is a place. Somebody share, please, how is it necessary to store the time of day so that it does not fit?
For ASE 15.7, the description of how this data type behaves is slightly extended.
Adaptive Server Enterprise 15.7> Reference Manual: Building Blocks> System and User-Defined Datatypes> Date and time datatypes
datetime columns hold dates between January 1, 1753 and December 31, 9999. The level of granularity. The last digit of the second digit is always 0, 3, or 6. Other digits are rounded up; 2, 3, and 4 round to 3; 5, 6, 7, and 8 round to 6; and 9 rounds to 10, since the date of January 1, 1900 and 4 bytes: 4 bytes: 4 bytes:
That is, you record an object with one timestamp, and read “almost the same, sometimes even the same”. You can even a little into the future (for a millisecond) to go if the nine falls out.
Well, this is documented, so this is “not a bug, but a feature”, no complaints about Sybase.
With all this, in ASE 15.7 there is
bigdatetime columns hold dates from January 1, 0001 to December 31, 9999 and 12: 00: 00.000000 AM to 11: 59: 59.999999 PM. Its storage size is 8 bytes. Bigdatetime is a 64 bit integer containing the number of microseconds since 01/01/0000.

The moral of this post: RTFM and use bigdatetime, Luke!

')

Source: https://habr.com/ru/post/303052/


All Articles