Hi everyone. I have been thinking about it, can't seem to get my head around it. I want to implement a piece of code that would increment a variable stored to EEPROM, when the year rolls over from 99 to 0 in DS3231, but only when the change occurs naturally. And not change the variable if the year is stored as 0 by user.
I could ofcourse, write it so that the changes occurs at every rollover regardless of method, and decrement if change is made by the user, but that doesn't seem like a viable method.
Otherwise, what logic or pattern could be used in code do differentiate between a natural rollover and user change? I don't mean the exact code, I mean summary in a few words.
I believe the century rollover was intended to cover the 1999 to 2000 rollover in older versions of the chip and has simply been carried over in later versions.
The leap year handling of the rollover 2099 to 2100 will not be correct.
you have high hopes for your projects in terms of lifetime but those who faced the year 2000 challenge were victim of the belief that the code that was written in the 70s and 80s (and even 90s) would no longer be around in 2000...
the DS3231 does have a builtin EEPROM, so you could store there the current year (every time you see a change in year when reading time) and initialize a year offset to in EEPROM to 0.
When noticing the transition from 99 to 0 you increase the offset
Of course that offset would have to be taken into account in all the methods that deal with time / year. OOP could make that pretty transparent.
If your code monitors the time from the RTC every second, it could detect the change from 99-12-31 23:59:59 to 00-01-01 00:00:00 and update the EEPROM then. Your user could reset the year to 0 during that same second, but would that really be a problem?
Actually, I was thinking about it too. Lol. I think I can set the time to 31 December, 99. And watch for the natural rollover to occur and reupload the code.
I have thought about this option, but I was sort of hoping that there could be some smart way to do it fail safe. Not that it is really needed, it's just that I'm curious.
My clock has a time setting mode, in which time gets set and stored after which the normal clock mode is resumed again. Can that be used? The problem is that if check the condition for normal clock mode and a specific second, that second may coinside with both normal clock mode and setting mode.
So, I'm not quite sure how to go about it. Perhaps, check if 00.00.00 01.jan is reached in normal clock mode? But then again, that could happen after user change. So, a bit confused.
because it's an easy way to capture the century change. if you see only 0 for the century and you don't have a sense for the previous value, you don't know if you need to increase the offset - and you want to do that only once it goes from 99 to 0
good point also on the leap years. don't know if they are taken into account correctly thereafter
I have written a good implementation for leap years. I just need to figure out the rollover issue. Thanks. But I still don't get why checking for the year change every year is required.
if you don't track year change, how do you plan to manage the offset? what algorithm will you use to ensure you set it to +1 only once?
EDIT: Just got what you are saying. You mean using the century bit (bit 7 of the month register) of the DS3231 which is toggled when the years register overflows from 99 to 00. Yes that would work.
There are, of course, other time related problems which will occur well before the rollover into the next century. Two are here:
Network Time Protocol (NTP) 00:00:00 UTC on 08 January 2036 ( unsigned 32 bit full seconds part of a 64 bit unsigned number )
UNIX timestamp 03:14:07 UTC on 19 January 2038 ( unix time represented as a signed 32 bit number )
Assuming that you check the RTC time once every hour (timing with the arduino*), you store the last (valid) time stamp in Arduino's EEPROM. The next time you check the time, you must verify that approximately one hour has elapsed since the time stored in EEPROM. If so, store the new time to EEPROM and if not, the RTC ha been tampered with.
*) In order to do this precisely, you must sync "the speed of time" for Arduino and RTC.
You can find lots of topics on how to do this. You need to track the entire year in a variable and the day of the year in another variable, and use one of numerous algorithms to determine if it's a leap year and calculate the date accordingly.
You can store those two variables in the EEPROM.