This library evolved from procedural code that I've been using for about a year. All feedback welcome.
The Timezone library facilitates time zone conversions and automatic daylight saving (summer) time adjustments. This is accomplished by setting a Real Time Clock (RTC) to Universal Coordinated Time (UTC) and then converting UTC to the correct local time, whether it is daylight saving time (a.k.a. summer time) or standard time.
The Timezone library is designed to work in conjunction with the Arduino Time library at Arduino Playground - Time. To download and use the library, including documentation and example sketches:
Uncompress the downloaded file. This will result in a folder containing all the files for the library, that has a name that includes the branch name, for example "Timezone-master".
Rename the folder to just "Timezone".
Copy the renamed folder to the Arduino sketchbook\libraries folder.
robtillaart:
Very usefull as there are many questions about getting the time zone right (after I had written an NTP-RTC article on the playground).
I am wondering about the DST algorithm, does it include Europe? did not dive into the code yet
Hi Rob, yes it should work for Europe, see the "WorldClock" example supplied with the library. The examples should work right out of the box on a bare Arduino. Glad to have you kick the tires, let me know if you find issues!
Should also work in the Southern hemisphere, I knew Nick would never let me live it down otherwise
The algorithm works from rules that you supply. For example, US Eastern Daylight Time, which has a UTC offset of -240 minutes, starts on the 2nd Sunday in March at 02:00 local time. So the rules are coded, in pairs, like this:
For the countries that do not have DST, only an offset to UTC, a 3rd constructor would make sense. This would imply one object less. alternative is to use a single object for both parameters?
Using EEPROM for storing DST makes sense, alternative is to put the TZ in PROGMEM as timezones are typically known at compiletime? Yes I can imagine at least 2 applications where this is not true.
Maybe an array of the 24 TZ's in Progmem (=288 bytes)?
Rob, thanks for the feedback! Actually I had changed the ReadMe file as follows but haven't pushed it up to github yet. So one less object this way as well:
For a time zone that does not change to daylight/summer time, pass the same rule
twice to the constructor, e.g.:
Timezone usAZ(usMST, usMST);
In fact the WorldClock example does this for Arizona:
//US Mountain Time Zone (Denver, Salt Lake City)
TimeChangeRule usMDT = {"MDT", Second, dowSunday, Mar, 2, -360};
TimeChangeRule usMST = {"MST", First, dowSunday, Nov, 2, -420};
Timezone usMT(usMDT, usMST);
//Arizona is US Mountain Time Zone but does not use DST
Timezone usAZ(usMST, usMST);
Still there should be little harm in the additional constructor, so I think I will add it.
In reality there are more than 24 timezones, given that a lot of locales use DST. So to predefine the 24 "standard" time zones, i.e. Alpha, Bravo, Charlie, etc. may not be all that useful. I didn't intend the library to replace the tz database, and thereby be at the whim of numerous governmental decisions
Thanks again, let me know if you have further suggestions!
should the EEPROM address be checked if it is valid / in range. And that there are 2 x 12 bytes free after it. Or a note in the readme.txt ...
_dst.offset * SECS_PER_MIN (+other) is calculated 8 times, maybe the internal representation could be an long which is calculated only once.
you would get rid of all multiplications for only 4 bytes extra per TZ. Don't know if and how much smaller the footprint of the lib would become .
(1) The ReadMe does talk to the size of the TimeChangeRule, and that could be elaborated on. Being very conscious of resources, mostly size in this case, I'm not terribly inclined to check the address. I also see that the Arduino EEPROM library doesn't validate addresses.
(2) Yes that bothered me just a little. Like I said, I didn't want to waste space, but on the other hand I didn't sweat processing overhead terribly, my assumption there being that there just isn't a lot of reason to do time zone conversions very frequently. I'd think once per second would be about it, that being the typical RTC resolution. BUT still a good point that is worth experimenting with. One of those things that I just didn't think through any further at the time.
(2) I did some testing with the worldclock sample yesterday and a version in which the TimeChangeRule was using a long (calculated in the constructor) and no multiply in the functions was larger than the original. If I recall correctly orig==7508 and new==7632 This seems quite an increase as there are only 9*2 TimeChangeRules = 18 rules * 2 bytes = 36 bytes more memory and there should be less math...
(1) No big deal, EEPROM will probably wrap around as the higher addresslines are ignored...
Hi Jack, thanks for this fine library! I recently wrote decoder DCF77 library (for the atomic time broadcasted by the DCF77 radiostation) (see this thread) which now includes an example of usage together with your TimeZone library.
Before I read the TimeZone README I had not considered that converting from local time to UTC is ambiguous in the hour before switching to winter time. Luckily for us DCF77 users, the DCF77 data package includes info about DST, so in the latest version I added a function to the library that unambiguously converts CET to UTC time.
Hi mrTee, thanks for the feedback, glad you found the library useful! We have WWV here which is similar to DCF77 in that it has a DST/Summer time indicator. Have not tried a WWV receiver myself, although I do have several clocks around that pick up the signal.
Yes daylight and summer time is evil with the ambiguity. Back in the day, every fall we used to have to shut the mainframe computers down and let them sit for an hour, else, the system and applications could generate redundant time stamps in logs and such. I'll have to ask around and see if they ever fixed that! My preference is to always use UTC internally and convert it to local time for human consumption.
I am trying to work on a DCF77 radio controlled clock with timezome support but it guess I need a bit of help with finding the timezone selection.
What I am trying to do is the following :
I would like to be able to select a timezone (with switches on the Arduino board).
At this moment I am stuck with the CET (Central European Time) showing on the LCD.
I was thinking if condition in the setSyncProvider line or unsigned long getDCFTime() {.... But no luck yet.
americo1977:
I would like to be able to select a timezone (with switches on the Arduino board).
At this moment I am stuck with the CET (Central European Time) showing on the LCD.
Hello!
Rather than using a hard-coded Timezone to convert to local time, e.g.
time_t localTime = CET.toLocal(DCFtime, &tcr);
instead declare a pointer to Timezone and set it to point to the desired Timezone object. Then use the pointer variable to do the conversion to local time:
I don't see any logic in the sketch to actually read the switches, obviously that will be needed, and it will just need to set the pointer variable to the desired timezone. I think you're just asking about how to handle the timezone, so I'll assume you've got working with the switches figured out.
Here is a comprehensive example that works similarly. It uses US timezones rather than European but still should illustrate the technique
Thank you very much for your help, pointers are indeed better than the if or if else conditions.
Actually I already added the switches in the code because they will be used to select the timezone, instead of using a menu on LCD screen (I still have lots to learn, and I am not at this point yet).
MrGlasspoole:
Hi,
this library works only with RTC's?
Hello! The Timezone library is unaware of RTCs; it will work with or without one. It simply converts time values stored in time_t variables. Include the Arduino Time library to define the time_t data type.
Is there something like "Auto Daylight Savings Time" for ntp?
NTP sends UTC only, without adjustments for daylight time or time zone.
[quote author=Jack Christensen link=topic=96891.msg1449873#msg1449873 date=1383232148] NTP sends UTC only, without adjustments for daylight time or time zone.
[/quote]Thats the reason i was asking. So i can do it like my router with your library.
There i can set the Time Zone and NTP Time Server and have a Auto Daylight Savings Time checkbox.
Now i see "the Time library will function as a software RTC without additional hardware" in the readme.
So the first sentence "A primary aim of this library is to allow a Real Time Clock (RTC)" did confuse me.