Time.h library - adjustTime()

Hello

I've just started experimenting with the Paul Stoffregen Time library, so not up to speed yet.
I was looking for a method to reset an RTC (DS1307) minutes and seconds on a daily basis on a button press at, say, midnight (00:00:00) to correct any RTC drift, say 23:59:58 (slow) or 00:00:02 (fast) when compared to an MSF clock.

So far, this is what I have found (all seconds)
adjustTime(299) works
adjustTime(300) doesn't work
adjustTime(-300) works
adjustTime(-3600) works
adjustTime(-7200) works and tested up to -72000

So, any negative adjustment works, but positive adjustments only work up to and including 299 seconds.

In practice, the adjustment will hopefully be no more than a couple of seconds either way on a daily basis, so the apparent 300 second limit, if that's what it is, won't apply.

I do appreciate that adjustTime() does not set the RTC time, only the "Arduino" time

For what it's worth, this all became necessary through trying out various RTCs (DS1307, DS3231) and getting nowhere near the +/- 2-ppm accuracy claimed for DS3231. If anyone has found a consistently accurate RTC, I would be pleased to hear. The long term aim is to run Arduino clocks in things like central heating programmers and update all of them from a central MSF or GPS time-keeper. Most commercial offerings from the likes of Honeywell are appalling time-keepers

Any ideas?

Any ideas?

If you need to adjust the time in a positive direction more than 300 seconds, you could:

  1. Modify the library to remove the 300 second limit
  2. Call adjust as many times as needed to adjust the time in less than 300 second increments.

Cheers Paul
Is the 300 a documented limit? I haven't found any reference to it (just been reading the readme notes), or is there a mathematical reason that's escaping me? It seems odd that it works OK in one direction, but not the other.

Whatever, it's a lot better than my efforts to adjust the RTC with all the problems of rollover especially at 23:59:59 on December 30th.

Whatever, it's a lot better than my efforts to adjust the RTC with all the problems of rollover especially at 23:59:59 on December 30th.

You'd probably have more problems on the 31st, then.

Whoops
30 days hath September, April, June and November - all the rest have 31, except February.
Try coding that. Well spotted. At that time of the year the days merge into one.

Sketches with time are a pain - 0 to 59, 1 to 24, 1 to 31 (variable), 1 to 7 etc. - 1-second ripples through the lot. I had thought of updating at a safe time/date like 10:30:30 or waiting until the rollovers had rolled over. Need a decimal clock, but too late for that.

300 is a limit? I'd like to know if you do
Cheers

300 is a limit? I'd like to know if you do

300 is not a limit. From time.h

void adjustTime(long adjustment) {
  sysTime += adjustment;
}

I can not confirm your findings that adjustTime(300) "doesn't work". I added that call to the TimeSerial library example so that it is called every time seconds()==15, and the time will advance by 5 minutes.

Please post your code where adjustTime() does not advance as expected. I would expect that you have a problem with the serial entry of a value for adjustTime().

I think you are being burned by an issue in library.
I reported this a while back:

The reason you may some magic around the number 300 is that is sync provider time interval.

--- bill

Bill--I understand that the adjusted time will not persist through a synch to an external time source, but that is not the behavior which the OP described.

So, any negative adjustment works, but positive adjustments only work up to and including 299 seconds.

cattledog:
Bill--I understand that the adjusted time will not persist through a synch to an external time source, but that is not the behavior which the OP described.

Sure it is.
Consider this. When you call adjustTime() it adjusts that actual datetime time_t value.
The code that checks for when it is time to do a sync does it be comparing a pre-calculated next synctime to the current time_t value. i.e. it checks to see if synctime is > the current time_t value.

When you set the actual time to the future the sync code will "think" that time has actually advanced. If you sent it far enough into the future, it will be beyond the next synctime and so the sync code will immediately do a sync.
But if you set it into the past, (no matter how much), the sync code will just wait longer until the next sync.

In this specific situation, I'm guessing that the reason the issue showed up for 300 but not 299 is not because 299 "works" and 300 doesn't, but rather due to the way the code was testing to see if it "worked".
i.e. the code probably read the time immediately after doing adjustTime() but if adjustTime() pushes the time into the future far enough (300 seconds is the magic number) then the sync code will run immediately on the next request for the time (before the time is returned), and therefore clobber the adjustment just made.

In reality the issue exists for positive and negative values regardless of their size.
What can vary is when the issue will show up since it is based on the amount of adjustment.

Note:
There was another related issue to this that I also reported. I'm not sure if was fixed or not.
At one point, I had offered a patch to the code that would also patch the synctime whenever a adjustTime() was called to work around this issue.

In the bigger picture the current use of adjustTime() is very problematic as it doesn't work with a sync provider. And this can't be really be fixed since in many cases you can't change the actual time in a sync provider.
(think GPS or NTP)

The real issue as I see it, is that people are often trying to use adjustTime() to create a time offset when using a sync provider. And that doesn't work.

But you can't simply change it to use an offset instead.

The issue with this is that it would break quite a bit of code that does this to set an RTC:
-adjustTime()

  • read the time
  • use the time read to set the RTC.

But I think that sequence is problematic anyway and should not be used.
There are other simple ways to do the very same thing when using an RTC.

I think that answer is to add a new Time library API function to create a time offset.
That would do what many people want and even allow a quick and easy way to support timezone offsets.

--- bill

Consider this. When you call adjustTime() it adjusts that actual datetime time_t value.
The code that checks for when it is time to do a sync does it be comparing a pre-calculated next synctime to the current time_t value. i.e. it checks to see if synctime is > the current time_t value.

When you set the actual time to the future the sync code will "think" that time has actually advanced. If you sent it far enough into the future, it will be beyond the next synctime and so the sync code will immediately do a sync.
But if you set it into the past, (no matter how much), the sync code will just wait longer until the next sync.

In this specific situation, I'm guessing that the reason the issue showed up for 300 but not 299 is not because 299 "works" and 300 doesn't, but rather due to the way the code was testing to see if it "worked".
i.e. the code probably read the time immediately after doing adjustTime() but if adjustTime() pushes the time into the future far enough (300 seconds is the magic number) then the sync code will run immediately on the next request for the time (before the time is returned), and therefore clobber the adjustment just made.

Thanks Bill. You've explained it clearly.