I really haven’t seen any projects that have examples that are using NTP, timezones and timezone strings correctly.
(I created an example that is attached)
I think much of the problem is that most people seem to be unaware of how unix solved how to handle time, timezone offsets and DST offsets decades ago as they are often trying to apply some other mindset of how to handle time and time zone offsets and end up doing things incorrectly or breaking existing unix/POSIX time APIs that have been in existence e and working for 30-40 years.
This is particularly true in the Arduino world.
While some libraries do use unix style time_t epoch values, they are not really using the time_t values correctly when managing timezones and timezone offsets.
What you really want is to use a POSIX compliant time library that has a complete implementation that includes timezone support with support for a POSIX/GNU timezone string: TZ Variable (The GNU C Library)
The latest AVR libC library does have many of the POSIX time calls and has some calls to support timezone offsets, but as I recall, the epoch that they chose to use is different than that standard unix epoch. This can create issues depending on what the timestamp needs may be.
IMO, I wouldn’t use an AVR for something like this. I’d use the ESP.
The esp8266 library code comes with full NTP support and a POSIX compliant time library including support for GNU timezone strings. It is very complete.
There is no need to add or use any 3rd party library to handle time or timezone offsets including DST changes.
Unfortunately, there is not an example provided that shows how to use them. Also there are some serious bugs in the timezone offset code. I have reported it:Serious issues with timezone support in time functions · Issue #4637 · esp8266/Arduino · GitHub
This is another great example of how timezone offsets are not being handle correctly and the way they tried to do things, not only was unnecessary but also breaks many other things including other code that already properly handled timezone offsets.
I’m probably going to be the guy that provides the patches to fix them as I already know what the fixes are and they are not complicated.
I’ll also be providing some new examples that will show how to properly use the time libraries with/without NTP and with/without and RTC.
I haven’t gotten around to it yet.
Unfortunately, to fix the time zone offset code work correctly breaks existing code that is using the way the code currently works.
There is no easy solution for this that fixes the issue and preserves existing code and that is likely to be the big issue with respect to actually fixing this.
i.e. the ESP guys may not want to actually fix it do to it breaking existing code.
That said, there is a really easy way to avoid the broken timezone offset code.
There is no need to use that broken attempt at timezone offsets anyway, so not using it is the simple solution.
If you simply never use the timezone offset in configtime() by setting the offsets to 0 and use a proper timezone TZ string things will “just work” as they are supposed to.
Here is the magic to use NTP with a timezone string on the ESP8266.
The key is to configure the time code to use NTP, but DO NOT use the timezone offset support.
That offset code is totally broken.
You then set a timezone TZ string to be a gnu timezone string which indicates the timezone, offset, and when DST changes are. This is used by the gnu time code when doing local time conversions so all the “ctime” calls to things like ctime(), localtime(), asctime() etc… will work properly including with local time zone offsets and DST time changes.
i.e. all the time calls will “just work” as they should.
All that boils down to a few includes and a few lines of code.
#include <time.h> // time() ctime()
#include <sys/time.h> // struct timeval
#include <coredecls.h> // for optional settimeofday_cb()
Code you put in setup()
settimeofday_cb(time_is_set_callback_function); // optional: callback function to call whenever time is set
configTime(0, 0, "pool.ntp.org");
setenv("TZ", "CST+6CDT,M3.2.0/2,M11.1.0/2", 1);
I created a simple working example that is attached.
In a real project, I would recommend using the wifi manager access point to get the WiFi ssid & password as well as adding extra parameters to get the ntp site and TZ string.
NTP-Clock-MinExample.ino (3.17 KB)