espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.52k stars 7.39k forks source link

Timezone Library support #403

Closed lonerzzz closed 7 years ago

lonerzzz commented 7 years ago

It would be good to have Timezone library support on the ESP32. I don't know enough background about the RTC on the ESP32 at this point but would be willing to investigate if nobody else is working on this. If anyone has initial input, please provide it.

copercini commented 7 years ago

Is SNTP what you are looking for? https://github.com/espressif/arduino-esp32/issues/231

lrmoreno007 commented 7 years ago

I think it refers to how to set the time in the RTC system and how to pick it up from the system, without having to connect to an SNTP server every time.

BTW The code in #231 fail with named servers and run OK with IP server:

Don't work

#include "time.h"
void printLocalTime()
{
    struct tm timeinfo;
    if(!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
        return;
    }
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

configTime(-7200, 3600, "pool.ntp.org");

Work OK

#include "time.h"
void printLocalTime()
{
    struct tm timeinfo;
    if(!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
        return;
    }
    Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

configTime(-7200, 3600, "69.10.161.7");

And gmtOffset_sec are inverted. In Spain is GMT +1 and I must use -3600 (7200 in the example) configTime(-7200, 3600, "69.10.161.7"); must be configTime(7200, 3600, "69.10.161.7");

Regards.

lonerzzz commented 7 years ago

From my experience, the timezone is something that has to be configured on your device to handle daylight savings time and the actual time of day. NTP only gets you the minute and second detail but the NTP server cannot tell you which hour of the day it is where your device is located without the timezone detail. If you are working on devices that have to show time or control based on time of day, you need Timezone support coupled with NTP.

lrmoreno007 commented 7 years ago

Ah OK, that's what is configured with:

void configTime (long gmtOffset_sec, int daylightOffset_sec, const char * server1, const char * server2, const char * server3)

GmtOffset_sec is the GMT Offset of your location, for example in Spain is GMT + 1 hour ---> 3600 *** As I said I think there is a problem and you have to enter it in negative ---> -3600

DaylightOffset_sec is the difference in hours between daylight saving time and regular time (winter - summer), for example in Spain is 1 hour ---> 3600

MarkusAD commented 7 years ago

@lonerzzz I see from cores/esp32/esp32-hal-time.c that basic timezone functionality is there, but is still somewhat tied to CST/CDT timezone info. Even though it lets you input GMT and DST offset, the clock here always read an hour fast or slow. Timezones work nicely in esp-idf... and allows telling it when DST begins and ends:

setenv("TZ", "EST5EDT4,M3.2.0/02:00:00,M11.1.0/02:00:00", 1); tzset();

Looking forward to having the same functionality in arduino.

everslick commented 7 years ago

timezone handling in a clean and generic way would be really nice. i have rolled my own and it is not trivial. the biggest issue is to decide if DST is currently active or not based on the rules that apply to your zone. you also want to keep the overhead down and not evaluate the DST rules each time you read the clock.

can we wrap the IDF functions to give them an Arduino like API?

for ref:

https://github.com/everslick/genesys/blob/master/src/i18n.h https://github.com/everslick/genesys/blob/master/src/system.cpp#L76

i also spent a good deal of time on giving my NTP and DS3231 code millisecond precision, which i have not seen elsewhere.

lonerzzz commented 7 years ago

I have a ported version of TimeLib and Timezone that I have been using for a month which look a lot like the standard Arduino implementations except where implementation collides. TimeLib is ESP32 specific but Timezone could work with either ESP32 or ESP8266. @me-no-dev would it make sense to have these in the libraries folder here or in a separate project? I will submit a pull request if you wish to include.

MarkusAD commented 7 years ago

I don't think any external libs are needed since all the underlying functions time() localtime() strftime() tzset() etc are already there in the sdk. Mainly what is needed is a better wrapper for setting TZ which was started in configTime() but is incomplete. I too have been using TimeLib/Timezone on other mcu for a couple years and would much prefer the standard unix functions.

MarkusAD commented 7 years ago

This code seems to work but there is nothing to tell it when DST begins and ends as it does in esp-idf...

struct tm timeinfo; configTime(5*3600, 3600, "my.ntp.server", NULL, NULL); // EST5EDT while (!getLocalTime(&timeinfo)); Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");

WALLTECH commented 7 years ago

@lonerzzz Could you please link your ports? I'd like to try them out.

MarkusAD commented 7 years ago

Question: Why does configTime() need to know long integer and integer offsets and do a bunch of massaging on them when it could just call setenv() and tzset() given the TZ parameters (as a character array) like used in esp-idf? This works so neatly and cleanly in idf...

setenv("TZ", "EST5EDT4,M3.2.0/02:00:00,M11.1.0/02:00:00", 1); tzset();

me-no-dev commented 7 years ago

because those were not in idf when this code was written :D

me-no-dev commented 7 years ago

@MarkyAD feel free to PR this update ;)

MarkusAD commented 7 years ago

Following up... I got my clock to be happy with sntp+timezones and sent a PR (after goofing up the first one, my git-skills are lame). The RTC is quite stable, although it has a consistent -1 second offset. Maybe due to network delay, I'm not sure, but its fine for messing around. With some luck I'll be able to get it to tick more in sync with my other ntp and gps clocks.

me-no-dev commented 7 years ago

Nice :) I am closing this now :P

lonerzzz commented 7 years ago

@me-no-dev It looks like my PR got hijacked. I had asked the question above about using my ported version of Timezone and TimeLib. I am still wondering if that is more appropriate because the additional wrappers that @MarkyAD provided are not, to my understanding, consistent with the Arduino approach that most people will be familiar with. The idea of the ported libraries was to provide an interface similar to what has been a standard approach for Timezone with Arduino while using the underlying functionality. Thoughts?

me-no-dev commented 7 years ago

@lonerzzz it is true that it is not a standard Arduino. All it does is expose the TZ api to people that need it. Adding libs is a totally different thing. Will you PR those? Let's have a look!

edautz commented 7 years ago

@lonerzzz, I got some strange issues when using the TimeLib of Paul Stoffregen on the ESP32. Can you supply a link to your ported library.

zafrirron commented 6 years ago

@lonerzzz

Since I've wasted A LOT of time on getting NTP time to work (paying for my stupidity), I hope this may save some time for others.

When calling configtime with NTP server name (like "pool.ntp.org"), you better make sure you have a valid DNS settings (to resolve the domain name).

A valid DNS will be available if you started the network connection with default parameters (like Wifi.begin(ssid,sspass), but will not be available in case you started your network connection with WiFi.config(IP,gateway,subnet) (used to get fix IP) without giving it valid DNS -> WiFi.config(IP,GW,SUB,DNS1,DNS2)!!!

So looking at @lrmoreno007 sample code snippet, I see that when giving configtime an IP it worked (no need for DNS resolution) but did not work with "pool.ntp.org" since no DNS was available to resolve it to IP, indicating you may had similar issue......

Matheus-Garbelini commented 6 years ago

@lonerzzz please share your library