RTClib icon indicating copy to clipboard operation
RTClib copied to clipboard

Range of year is very restrictive

Open pjdupreez opened this issue 1 year ago • 2 comments

Maybe I am missing something, or the reason behind it, probably because of Y2K of some such reason, so please enlighten me, or add a clear note to the documentation.

The range of the year is (2000 -- 2099). This seems a bit restrictive, especially when trying to do get the difference between 2 dates in 2 different centuries.

For example: ` DateTime now = DateTime (2023, 7, 19); DateTime then = DateTime (1980, 5, 25);

Serial.print("Now: "); Serial.print(now.year(), DEC); Serial.print('-'); Serial.print(now.month(), DEC); Serial.print('-'); Serial.println(now.day(), DEC);

Serial.print("Then: "); Serial.print(then.year(), DEC); Serial.print('-'); Serial.print(then.month(), DEC); Serial.print('-'); Serial.println(then.day(), DEC);

// Serial Output // Now: 2023-7-19 <-- correct // Then: 2188-5-25 <-- problem `

Like I said, I probably missed the reason for this decision, if it is documented, so would like to know if there is a way around this limitation. Thanks

pjdupreez avatar Jul 16 '23 07:07 pjdupreez

The range in indeed a bit restrictive. The main reason, I believe, is that this library is meant for interfacing RTC modules. As you would use such a module to get the current date and time, the representation of historical dates falls then out of the scope of the library. Also, it turns out that most RTCs represent the year as one byte in BCD format (binary coded decimal). The year field hosts two decimal digits, which restricts the representable range to one century.

The DateTime class does not use BCD internally, and could in principle be extended to cover a wider range. Please, see issue #146 for some considerations which lead to the current choice.

especially when trying to do get the difference between 2 dates in 2 different centuries

This should work:

// From 1980-05-25 to 2000-01-01.
const uint32_t seconds_from_then_to_2000 = 618624000;

DateTime now = rtc.now();
uint32_t seconds_from_then_to_now =
         seconds_from_then_to_2000 + now.secondstime();

Edit: If you don't mind assigning a negative value to an unsigned number (which some may find objectionable), the following should also work, thanks to the rules of modular arithmetic:

uint32_t then = -618624000;             // 1980-05-25
uint32_t now = rtc.now().secondstime();
uint32_t seconds_from_then_to_now = now - then;

edgar-bonet avatar Jul 16 '23 09:07 edgar-bonet

Thanks for the clarification. Does make sense if the purpose is only for interfacing with RTC, I suppose.

Ended up going 'old school' and doing the calculation by using seperate ints for year, month day (for other centuries) and using current time from RTC as inputs. Very verbose, but couldnt be bothered to find a library to do to that for me 😅

On Sun, 16 Jul 2023, 11:35 Edgar Bonet, @.***> wrote:

The range in indeed a bit restrictive. The main reason, I believe, is that this library is meant for interfacing RTC modules. As you would use such a module to get the current date and time, the representation of historical dates falls then out of the scope of the library. Also, it turns out that most RTCs represent the year as one byte in BCD format (binary coded decimal). The year field hosts two decimal digits, which restricts the representable range to one century.

The DateTime class does not use BCD internally, and could in principle be extended to cover a wider range. Please, see issue #146 https://github.com/adafruit/RTClib/issues/146 for some considerations which lead to the current choice.

especially when trying to do get the difference between 2 dates in 2 different centuries

This should work:

// From 1980-05-25 to 2000-01-01.const uint32_t seconds_from_then_to_2000 = 618624000;

DateTime now = rtc.now();uint32_t seconds_from_then_to_now = seconds_from_then_to_2000 + now.secondstime();

— Reply to this email directly, view it on GitHub https://github.com/adafruit/RTClib/issues/289#issuecomment-1637036555, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH4NCAMVFPHBRYWCNDIN33XQOYVDANCNFSM6AAAAAA2LYK7GU . You are receiving this because you authored the thread.Message ID: @.***>

pjdupreez avatar Jul 17 '23 07:07 pjdupreez