Converting UNIX 1970 to my own timezones by adding seconds

Its been a while since I looked at the ESP32 code.
From that code fragment, it looks like the ESP32 code has updated how they deal with the configTime() offsets.
The old code patched a global down in the NTP code to dork with the time_t value so it really mucked things up. - and it only worked with NTP was successfully running and didn't apply to all the APIs that may set/get the time.

So that new code looks like it may work to set a fixed offset by creating a fake TZ string for the fixed offset.

But I'd still recommend using setenv() and tzset() directly so you can set your own timezone string to get your own proper local automatic DST adjustments so that the time will move forward and back as needed at the proper times.

--- bill

1 Like

Must be on guard against making "Better" the enemy of "Good Enough".

Sure but if you don't use/set your own TZ string the offset will be a fixed constant from UTC and so you won't get any kind of automatic DST adjustment which means if the local timezone does DST you will have do manual adjustments twice a year or write some other code to duplicate the automatic DST changing code that is already in the time library.

Just me, but IMO, if the local timezone does DST adjustments, then it is not really any more effort to do two additional API function calls one time during setup() to set a TZ string with the local timezone rules to ensure the DST adjustments of the local time happen automatically. The code is there to support automatic DST adjustments so why not use it?

--- bill

1 Like

Im initializing an RTC clock after doing an NTP request for epoch1970 time and converting the time to years, months, and so on... I'm using the Timezone library for the timezone conversion and RTCZero for initializing the RTC clock. My Arduino is the MKR NB 1500 which has a "SAMD21 Cortex®-M0+ 32bit low power ARM MCU". A snippet of my code is below:

    /**UNIX_adjusted_No is the epoch1970 adjusted to my timezone using the TimeZone library
    * The timezone conversion was done correctly, I have checked multiple times.
    */
    const int RTC_second = second(UNIX_adjusted_No); 
    const int RTC_minute = minute(UNIX_adjusted_No);
    const int RTC_hour = hour(UNIX_adjusted_No);
    const int RTC_day = day(UNIX_adjusted_No);
    const int RTC_month = month(UNIX_adjusted_No);
    const int RTC_year = year(UNIX_adjusted_No);
    
   
    rtc.begin();
 
    rtc.setYear(RTC_year);
    rtc.setMonth(RTC_month);
    rtc.setDay(RTC_day);
    rtc.setHours(RTC_hour);
    rtc.setMinutes(RTC_minute);
    rtc.setSeconds(RTC_second);

    Serial.println(rtc.getYear());

But "Serial.println(rtc.getYear());" returns "39-3600" when it should return 2023. Has anyone also experienced this?

Why do you keep starting new threads on the same topic?

Why are you still posting "snippets"?

The error is often in the code you dont post.

Related topics merged as requested.

Best wishes for success with your project @thehumblearduinoer

pert

Actually, for me being on USA East Coast, this code works perfectly to set the TZ string:

#include "esp_sntp.h"

void setup() {
  Serial.begin(115200);
  delay(1000);
  const char ntpServer[] = "pool.ntp.org";
  const long gmtOffsetSec = -5 * 3600L;
  const int daylightOffsetSec = 3600;

  configTime(gmtOffsetSec, daylightOffsetSec, ntpServer);
  char *tz = getenv("TZ");
  if (tz != nullptr) {
    log_i("TZ value after configTim() = %s", tz);
  } else {
    log_i("No TZ Environment Variable Found");
  }
}

void loop() {
}

The resulting output is:

[  1056][I][sketch_feb15b.ino:13] setup(): TZ value after configTim() = UTC5DST

That's exactly what I need ... 5 hour offset from UTC and automatic DST switching. The only thing configTime() doesn't seem to provide is the ability to change the DST switchover dates from their default March / November values.

GMT+1 is a different beast than CET/CEST

Time math is always horrible.

Use UTC for everything inside the computers and communication, including the RTC, and convert to the timezone time only for the UI. Maybe attach a pin to a switch for the user to toggle for standard/summer time offset so when it goes wrong, the user can fix it.

That is literally exactly what I just said.
You can use the offset stuff on the ESP32 (not on the ESP8266) and it automatically internally creates a TZ string for you. But the automatically created TZ string does not have the rules for DST adjustments.
So you won't get the automatic DST adjustments
See post #23

So why not just do the API calls were you can set the actual TZ string so the DST adjustments work vs just setting a fixed offset? It is no more effort.
For USA central timezone the TZ string is "CST+6CDT,M3.2.0/2,M11.1.0/2"
See here for how to create the TZ string:

--- bill

1 Like

I disagree. The automatically-created TZ string in my example is: "UTC5DST". From what I've read online, that "DST" is sufficient to give you an automatic local time DST switch of 1 hour (the default) and the time switchover will happen on the default dates in March and November.

Have you verified this does adjustments on the ESP32 platform?

So far I've not been able to confirm this.
(I may not yet have looked deep enough, and I have not yet tried it on actual h/w)
I could build some test code and try it on real h/w but I prefer to see the actual code with my own eyes.

I looked around at various ESP32 documentation and glibc/timezone source code and it was not clear to me if automatic adjustment is assured to be the case with that TZ string on the ESP32.
The ESP32 documentation refers to the POSIX TZ page that I previously linked to.

From the POSIX TZ documentation, if the offset,start/time,end/time are omitted, the timezone rules will default to what is in /usr/share/zoneinfo/posixrules
I was able to find references to this in the glibc time code.
(On linux the posixrules file links to America/New_York tzfile which are the timezone rules in New_York which are the same as most of the USA)

What isn't clear is what this does in the ESP32 environment.
I've not been able to locate the glibc/time code that is used on the ESP32 to see if they are using the stock code or if they have modified it.
(The ESP8266 core has modifications in the some of time code)

There are some conditionals in the glibc time code as well as some aliases.
So depending on how they ported this to the ESP32, it may or may not have the same behavior as the POSIX code.

Does anybody have a link to the glibc time code that is being used on the ESP32?

But from a portability point of view, even it does "work" on the ESP32, it would only work for whatever default timezone rules were configured in the ESP32 code - which if the ESP32 code sticks to the spirit of the original glibc time code, would be New York. While those rules apply to most locations in the continental US, it isn't universal.
Also, using the offset parameters on the configTime() API call doesn't work on the ESP8266.

I would still stick with explicitly setting the TZ to with the proper timezone information and rules so it is obvious what the rules are, works for any timezone in the world and works on any platform that supports the glibc time functions.
i.e. using and setting an explicit TZ string will work on both the ESP32 and ESP8266 whereas using offsets will not work on the ESP8266.

--- bill

Guess we'll find out on March 12.

I tested it on actual h/w with a manual time set to a couple of seconds before 2am March 12, 2023 eastern USA time, so it would rollover before NTP did a sync to the correct time.
It does do the DST adjustment.
at 2am March 12, 2023 it will jump to 3am on the US time change rule.

        ctime: Sun Mar 12 01:59:59 2023
 local asctime: Sun Mar 12 01:59:59 2023
gmtime asctime: Sun Mar 12 06:59:59 2023
      gmtime:isdst=0:yday=70:wday=0:year=123:mon=2:mday=12:hour=6:min=59:sec=59
   localtime:isdst=0:yday=70:wday=0:year=123:mon=2:mday=12:hour=1:min=59:sec=59
 
tz_minuteswest: 0, tz_dsttime: 0
gettimeofday() tv.tv_sec : 1678604400
time()            time_t : 1678604400
 
         ctime: Sun Mar 12 03:00:00 2023
 local asctime: Sun Mar 12 03:00:00 2023
gmtime asctime: Sun Mar 12 07:00:00 2023
      gmtime:isdst=0:yday=70:wday=0:year=123:mon=2:mday=12:hour=7:min=0:sec=0
   localtime:isdst=1:yday=70:wday=0:year=123:mon=2:mday=12:hour=3:min=0:sec=0

So if using offsets with configTime() on the ESP32 it will adjust local times according to US time change rules which can be convenient for US applications in the 48 states.

but it won't work on the ESP8266 since the offsets are broken in that core and it won't work in any location that doesn't do its time adjustments the same way the US 48 states do it.

For my stuff, I'll stick to specifying the full TZ string with the offset and the time change rules.

--- bill

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.