Timezone.h > check for DST change bug?

Arduino Nano 33 IoT with 'Clock.ino' example
Central European time zone

I can't get myTZ.locIsDST(now()) to work !?

After the time changes as it should, this value stays the same.
here is the Serial Monitor output when the changes happens from CEST to CET

00:59:53 Sun 31 Oct 2021 UTC   02:59:53 Sun 31 Oct 2021 CEST  is DST? 1
00:59:54 Sun 31 Oct 2021 UTC   02:59:54 Sun 31 Oct 2021 CEST  is DST? 1
00:59:55 Sun 31 Oct 2021 UTC   02:59:55 Sun 31 Oct 2021 CEST  is DST? 1
00:59:56 Sun 31 Oct 2021 UTC   02:59:56 Sun 31 Oct 2021 CEST  is DST? 1
00:59:57 Sun 31 Oct 2021 UTC   02:59:57 Sun 31 Oct 2021 CEST  is DST? 1
00:59:58 Sun 31 Oct 2021 UTC   02:59:58 Sun 31 Oct 2021 CEST  is DST? 1
00:59:59 Sun 31 Oct 2021 UTC   02:59:59 Sun 31 Oct 2021 CEST  is DST? 1
01:00:00 Sun 31 Oct 2021 UTC   02:00:00 Sun 31 Oct 2021 CET   is DST? 1
01:00:01 Sun 31 Oct 2021 UTC   02:00:01 Sun 31 Oct 2021 CET   is DST? 1
01:00:02 Sun 31 Oct 2021 UTC   02:00:02 Sun 31 Oct 2021 CET   is DST? 1
01:00:03 Sun 31 Oct 2021 UTC   02:00:03 Sun 31 Oct 2021 CET   is DST? 1
01:00:04 Sun 31 Oct 2021 UTC   02:00:04 Sun 31 Oct 2021 CET   is DST? 1
01:00:05 Sun 31 Oct 2021 UTC   02:00:05 Sun 31 Oct 2021 CET   is DST? 1
01:00:06 Sun 31 Oct 2021 UTC   02:00:06 Sun 31 Oct 2021 CET   is DST? 1

I tried daylightSavingTime = myTZ.locIsDST(local);
and daylightSavingTime = myTZ.locIsDST(now());

the complete code:

// Arduino Timezone Library Copyright (C) 2018 by Jack Christensen and
// licensed under GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Arduino Timezone Library example sketch.
// Self-adjusting clock for one time zone.
// TimeChangeRules can be hard-coded or read from EEPROM, see comments.
// Jack Christensen Mar 2012
#include <Arduino.h>
#include <time.h>
#include <Timezone.h> // https://github.com/JChristensen/Timezone

// Central European Time (Frankfurt, Paris)
time_t local, utc;
int daylightSavingTime = 0;

TimeChangeRule *tcr; // pointer to the time change rule, use to get TZ abbrev

TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};   // Central European Standard Time
Timezone myTZ(CEST, CET);

// declare functions
void printDateTime(time_t t, const char *tz);

void setup()
{
  Serial.begin(115200);
  setTime(23, 59, 40, 30, 10, 2021); //another way to set the time (hr,min,sec,day,mnth,yr)
}

void loop()
{
  utc = now();
  local = myTZ.toLocal(utc, &tcr);
  Serial.println();
  printDateTime(utc, "UTC   ");
  printDateTime(local, tcr->abbrev);
  
  daylightSavingTime = myTZ.locIsDST(local));

  Serial.print("  is DST? " + String(daylightSavingTime));
  delay(30);// delay shortened here and in Time.cpp to speed up time zone change
}

// format and print a time_t value, with a time zone appended.
void printDateTime(time_t t, const char *tz)
{
  char buf[32];
  char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer)
  strcpy(m, monthShortStr(month(t)));
  sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
          hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t), tz);
  Serial.print(buf);
}

Shouldn't it be myTZ.locIsDST(local); ?

I just changed that to try but no change??

EDIT !!

After the time changed to 03:00, so 1 hour AFTER the change from CEST to CET the DST check changed from 1 to 0??

Is this a bug??

00:59:53 Sun 31 Oct 2021 UTC   02:59:53 Sun 31 Oct 2021 CEST  is DST? 1
00:59:54 Sun 31 Oct 2021 UTC   02:59:54 Sun 31 Oct 2021 CEST  is DST? 1
00:59:55 Sun 31 Oct 2021 UTC   02:59:55 Sun 31 Oct 2021 CEST  is DST? 1
00:59:56 Sun 31 Oct 2021 UTC   02:59:56 Sun 31 Oct 2021 CEST  is DST? 1
00:59:57 Sun 31 Oct 2021 UTC   02:59:57 Sun 31 Oct 2021 CEST  is DST? 1
00:59:58 Sun 31 Oct 2021 UTC   02:59:58 Sun 31 Oct 2021 CEST  is DST? 1
00:59:59 Sun 31 Oct 2021 UTC   02:59:59 Sun 31 Oct 2021 CEST  is DST? 1
01:00:00 Sun 31 Oct 2021 UTC   02:00:00 Sun 31 Oct 2021 CET   is DST? 1
01:00:01 Sun 31 Oct 2021 UTC   02:00:01 Sun 31 Oct 2021 CET   is DST? 1
01:00:02 Sun 31 Oct 2021 UTC   02:00:02 Sun 31 Oct 2021 CET   is DST? 1
01:00:03 Sun 31 Oct 2021 UTC   02:00:03 Sun 31 Oct 2021 CET   is DST? 1
01:00:04 Sun 31 Oct 2021 UTC   02:00:04 Sun 31 Oct 2021 CET   is DST? 1
01:00:05 Sun 31 Oct 2021 UTC   02:00:05 Sun 31 Oct 2021 CET   is DST? 1
01:00:06 Sun 31 Oct 2021 UTC   02:00:06 Sun 31 Oct 2021 CET   is DST? 1
.
.
.
01:59:56 Sun 31 Oct 2021 UTC   02:59:56 Sun 31 Oct 2021 CET   is DST? 1
01:59:57 Sun 31 Oct 2021 UTC   02:59:57 Sun 31 Oct 2021 CET   is DST? 1
01:59:58 Sun 31 Oct 2021 UTC   02:59:58 Sun 31 Oct 2021 CET   is DST? 1
01:59:59 Sun 31 Oct 2021 UTC   02:59:59 Sun 31 Oct 2021 CET   is DST? 1
02:00:01 Sun 31 Oct 2021 UTC   03:00:01 Sun 31 Oct 2021 CET   is DST? 0
02:00:02 Sun 31 Oct 2021 UTC   03:00:02 Sun 31 Oct 2021 CET   is DST? 0
02:00:03 Sun 31 Oct 2021 UTC   03:00:03 Sun 31 Oct 2021 CET   is DST? 0
02:00:04 Sun 31 Oct 2021 UTC   03:00:04 Sun 31 Oct 2021 CET   is DST? 0
02:00:05 Sun 31 Oct 2021 UTC   03:00:05 Sun 31 Oct 2021 CET   is DST? 0
02:00:06 Sun 31 Oct 2021 UTC   03:00:06 Sun 31 Oct 2021 CET   is DST? 0
02:00:07 Sun 31 Oct 2021 UTC   03:00:07 Sun 31 Oct 2021 CET   is DST? 0
02:00:08 Sun 31 Oct 2021 UTC   03:00:08 Sun 31 Oct 2021 CET   is DST? 0
02:00:09 Sun 31 Oct 2021 UTC   03:00:09 Sun 31 Oct 2021 CET   is DST? 0

Maybe they want the timezone change rule to be in UTC and not local time.

1 Like

Good point but I tried both... same behaviour.

I think it is that the local time is ambiguous during the 1 hour changeover from CEST to CET.
For example 02:30:21 occurs twice in that hour. You've simply used a formula to determine if it (local) is DST or not i.e. daylightSavingTime = myTZ.locIsDST(local)); and it is not aware of which of the two possibilities you are referring to (i.e. the earlier 02:30:21 or the later 02:30:21 ).

1 Like

You are spot on of course.

But still as just a user of a purpose build and great library I did expect that a function which returns a value of the DST status would just work.

I have way too little experience to solve his but I will dive into it.
But a solution would be great though so expert input would be appreciated!

May I ask @khoih-prog for help as he has vastly improved the Timezone library but still with the same bug AFAIK?

I don't think it can really be solved and it not really a bug, it is an ambiguity inherent in the DST to StandardTime switch. When I design clocks, I always run these in UTC. I convert to local time for the display and I convert from local time when I set them. This reduces the problems.

It raises exactly the same issues as time_t toUTC(time_t local) which are described here: GitHub - JChristensen/Timezone: Arduino library to facilitate time zone conversions and automatic daylight saving (summer) time adjustments.

time_t toUTC(time_t local);

I suppose you could extend the TimeZone::locIsDST() method so as to have the following prototype :

bool locIsDST(time_t local, bool if_we_are_in_a_DST_to_StandardTime_transition_return_the_DST_variant ) ;

but that would be quite clumsy to use.

1 Like

Mabe use something like this as a workaround : daylightSavingTime = ( tcr == &CEST );

1 Like

YES! You are on the right track...

I figured out myself that checking for "CEST" was the way to go...

So I used this succesfully:
(String(tcr->abbrev) == "CEST") ? summerTime = 1 : summerTime = 0;

It is 'not done' to use String but I don't know how to do that so your solution would be better although it did not work.

Almost there...

isDST() can only be used with UTC time, but it does work. There is no transition problem with it. See reply #5. Whatever you "tried" with it must have a semantic error.

What is your problem, exactly?

Checking the time zone identifier and calling isDST(utc) should produce the same result.

1 Like

@aarg "isDST() can only be used with UTC time, but it does work"

That was the problem! I used the locIsDST(local) not utcIsDST(utc) That was the confusion for me because locIsDST() does also exist. Leaving only the question what is the use of locIsDST() ?

Thank you for helping me out! I am busy understanding what for me are 'black box' libraries to learn more and certainly I did. Spent the whole week on this... I envy those for who programming is a second nature.

sorry for not having understood your suggestion. I was stuck with the other function which is locIsDST(local). Thank you!