NorthernWidget / DS3231

Communicates between Arduino-programmed AVR and Maxim DS3231 RTC: splice of Ayars' (http://hacks.ayars.org/2011/04/ds3231-real-time-clock.html) and Jeelabs/Ladyada's (https://github.com/adafruit/RTClib) libraries
The Unlicense
183 stars 81 forks source link

Year 2106 potential problem? #82

Closed Macintosh-Fan closed 1 year ago

Macintosh-Fan commented 1 year ago

Could the following method be vulnerable to the Year 2106 Problem, since it returns an unsigned int? uint32_t unixtime(void) const;

Plus, I think for a unix timestamp, it should be given as an unsigned long.

IowaDave commented 1 year ago

Aha! Our Fearless Reader has perhaps discovered the exhaustive Wikipedia article on this subject!

The use of an unsigned 32-bit integer to represent a "Unix timestamp" is one of the limitations bearing on a programmer's decision to use this Library. This particular post focuses on a member function of the DateTime class.

The documentation in this repo for DateTime includes a disclaimer that the DateTime class "...is designed to work correctly only with dates between January 1, 2000 and December 31, 2099."

For the sake of completeness, at least two other limitations relate to representing years in the DS3231 hardware:

The hardware makes no claim of accuracy after 2099

The DS3231 hardware imposes a further constraint. On page 1 of the datasheet we read, "...Leap-Year Compensation (is) Valid Up to 2100." The DateTime functions and the DS3231 will encounter no difficulty with dates through December 31, 2099. The year 2106 is out of scope because it comes after 2100.

The hardware can represent only a 2-digit value for the Year

The DS3231 hardware register for Year is an 8-bit, binary-coded-decimal field, devoting 4 bits to each decimal place. When the hardware increments the year value from 0x99 it rolls over to become 0x00, rather than 0x9A or 0xA0. 99 is as high as the year can go in a DS3231.

In other words, once again, 2099 is kind-of the end because it makes little sense to revise the DateTime portion of the Library for dates that the hardware neither claims to support reliably nor is able to represent.

For the reasons given above, the documentation in this repo recommends using this Library only for dates in the range of January 1, 2000 through December 31, 2099. See the documentation for setEpochTime().

A code writer who insists on using this library for moments after 06:28:15 a.m. on 7 February 2106 (when the 32-bit UNIX timestamp values rolls over to zero) may still be able to make sense of the values they obtain. They will just have to make allowance for the roll-over in their code.

The OP is invited to submit a pull request amending the DateTime code to address this issue. Please include example programs demonstrating the revision for both AVR- and SAMD21-based platforms.

It might be marginally helpful to leave this Issue open, if only to make it easier for future readers to discover that this question has been asked and answered.

David