Timezone lib just not correct


I has used this lib for my timezone before https://github.com/mamuesp/timezones. Now tz still sync correctly to UTC I expected. but when I print local time it wrong

   time_t t = time(NULL);
    struct tm tm = *localtime(&t);
    uint16_t year = tm.tm_year + 1900;
    LOG(LL_WARN, ("##Year : %d",tm.tm_year + 1900));
    LOG(LL_WARN, ("##Month: %02d",tm.tm_mon + 1));
    LOG(LL_WARN, ("##Day  : %02d",tm.tm_mday));
    LOG(LL_WARN, ("##Hour : %02d",tm.tm_hour));
    LOG(LL_WARN, ("##Min  : %02d",tm.tm_min));
    LOG(LL_WARN, ("##Sec  : %02d",tm.tm_sec));

This is like 15hour behind the real time here.

[Dec 21 03:16:49.487] main.cpp:386            ##Year : 2022
[Dec 21 03:16:49.487] main.cpp:387            ##Month: 12
[Dec 21 03:16:49.492] main.cpp:388            ##Day  : 20
[Dec 21 03:16:49.492] main.cpp:389            ##Hour : 12
[Dec 21 03:16:49.497] main.cpp:390            ##Min  : 16
[Dec 21 03:16:49.497] main.cpp:391            ##Sec  : 50

This that about time api or something ? I used to work before

The library works very well. After changing timezone.olson you need to reboot the device because the timezone stored in sys.tz_spec is set early in the boot process.

Or you can setup the timezone in your code, after the first time sync and you don’t need to reboot.

#include "mgos.h"

static void timer_cb(void *arg) {
  static bool s_tick_tock = false;
  time_t now = time(0);
  struct tm timeinfo = {};
  localtime_r(&now, &timeinfo);
  char timestamp[24];
  strftime(timestamp, sizeof(timestamp), "%F %T", &timeinfo);
      ("%s uptime: %.2lf, now: %s, heap total/free/min_free: %lu/%lu/%lu",
       (s_tick_tock ? "Tick" : "Tock"), mgos_uptime(), timestamp,
       (unsigned long) mgos_get_heap_size(),
       (unsigned long) mgos_get_free_heap_size(),
       (unsigned long) mgos_get_min_free_heap_size()));
  s_tick_tock = !s_tick_tock;

  (void) arg;

static void time_change_cb(int ev, void *evd, void *arg) {
  static bool first = true;
  LOG(LL_INFO, ("%s - first: %s", __func__, first ? "true" : "false"));
  if (first) {
    first = false;
    // initialize TZ env variable with the sys.tz_spec config value
    const char *tz_spec = mgos_sys_config_get_sys_tz_spec();
    if (tz_spec != NULL) {
      LOG(LL_INFO, ("Setting TZ to '%s'", tz_spec));
      setenv("TZ", tz_spec, 1);

  (void) ev;
  (void) evd;
  (void) arg;

enum mgos_app_init_result mgos_app_init(void) {
  mgos_event_add_handler(MGOS_EVENT_TIME_CHANGED, time_change_cb, NULL);
  mgos_set_timer(10000 /* ms */, MGOS_TIMER_REPEAT, timer_cb, NULL);

Oops! Look like I found the problem. in the lib there is tz-archive.zip that store timezone convert into tz_spec.

My time zone is Asia/Singapore it return <+08>-8 And my time was far 15 hour behind.

After I stop used the lib and I did

mos config-set sys.tz_spec=“ICT-8”

Now my time it correct.

So is problem it about lib version or tz format is now change ?

The library and the embedded files are ok.
It looks like the formats like <+08>-8 or <+03>-3 are not correctly handled by the newlib in esp-idf, but it handles correctly formats like EET-2EEST,M3.5.0/3,M10.5.0/4"

I check tz-archive.zip file from gitrepo of the lib. it’s show <+08>-8. Or I miss understand something. because now what I did is change the valve of Asia/Singapore from <+08>-8. into ICT-8 so it working.