Help needed using Timezone library

Hi All,

I know that the problem here is me. If I load the clock example into my MKR Zero it works perfectly so I know the timezone library works.

Below is my code. Although i have been using various Arduinos for a while, I have to admit that i come from a windows background in VB and VBS so String is a lot easier that sting for me (I know, that's bad and I promise that i will try my best to move to string.

In the mean time, i have a problem where the Timezone library toLocal always returns a DST time. I have extracted the relevant code into a new sketch and teste it and its still doing the same. Could someone have a look at the code below and tell me what i am doing wrong.

The reason for the variables and rebuilding the the rules is because in the code, the rules are read in form a file and then split into the parts to be made into a rule. I have loaded the variable with what is read form the file.

Thanks
Ian...


#include <Time.h>
#include <TimeLib.h>

#include <Timezone.h>   // https://github.com/JChristensen/Timezone

#include <RTClib.h>

RTC_DS1307 rtc;

tmElements_t tm;

TimeChangeRule myDST = {"", 0, 0, 0, 0, 0};
TimeChangeRule mySTD = {"", 0, 0, 0, 0, 0};
Timezone myTZ(myDST, mySTD);

String tzDSTStartShortName = "BST";
String tzDSTStartDayNum = "Last";
String tzDSTStartDay = "Sun";
String tzDSTStartMonth = "Oct";
long tzDSTStartTime = 2;
long tzDSTStartDiff = 60;

String tzDSTEndShortName = "GMT";
String tzDSTEndDayNum = "Last";
String tzDSTEndDay = "Sun";
String tzDSTEndMonth = "Apr";
long tzDSTEndTime = 2;
long tzDSTEndDiff = 0;

char eventText[100];

void setup() {
 
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
  }
  
  setupTimeZones();

}

void loop() {

  DateTime now = rtc.now();
  time_t utc = now.unixtime();
Serial.println(utc);  
  breakTime(utc, tm);
  sprintf(eventText,"RTC Date/Time</td><td>%02d/%02d/%04d %02d:%02d:%02d",tm.Day,tm.Month,tm.Year + 1970,tm.Hour,tm.Minute,tm.Second);
Serial.println(eventText);

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


  time_t local_t = myTZ.toLocal(utc, &tcr);
Serial.println(local_t);
  breakTime(local_t, tm);

  sprintf(eventText,"Local Date/Time</td><td>%02d/%02d/%04d %02d:%02d:%02d %s",tm.Day,tm.Month,tm.Year + 1970,tm.Hour,tm.Minute,tm.Second,tcr -> abbrev );
  Serial.println(eventText); 
  

delay(10000);

}


//---------------------------------------------------------------
// Function to setup TimeZones
//---------------------------------------------------------------
void setupTimeZones() {

  char buffer[6];
 
Serial.println(tzDSTStartShortName);

  tzDSTStartShortName.toCharArray(buffer,5);
  strcpy(myDST.abbrev, buffer);
  if (tzDSTStartDayNum = "First") {myDST.week = First;}
  else if (tzDSTStartDayNum = "Second") {myDST.week = Second;}
  else if (tzDSTStartDayNum = "Third") {myDST.week = Third;}
  else if (tzDSTStartDayNum = "Fourth") {myDST.week = Fourth;}
  else if (tzDSTStartDayNum = "Last") {myDST.week = Last;};
  //myCEST.week = Last;

  if (tzDSTStartDay = "Mon") {myDST.dow = Mon;}
  else if (tzDSTStartDay = "Tue") {myDST.dow = Tue;}
  else if (tzDSTStartDay = "Wed") {myDST.dow = Wed;}
  else if (tzDSTStartDay = "Thu") {myDST.dow = Thu;}
  else if (tzDSTStartDay = "Fri") {myDST.dow = Fri;}
  else if (tzDSTStartDay = "Sat") {myDST.dow = Sat;}
  else if (tzDSTStartDay = "Sun") {myDST.dow = Sun;}
  //myDST.dow = Sun;

  if (tzDSTStartMonth = "Jan") {myDST.month = Jan;}
  else if (tzDSTStartMonth = "Feb") {myDST.month = Feb;}
  else if (tzDSTStartMonth = "Mar") {myDST.month = Mar;}
  else if (tzDSTStartMonth = "Apr") {myDST.month = Apr;}
  else if (tzDSTStartMonth = "May") {myDST.month = May;}
  else if (tzDSTStartMonth = "Jun") {myDST.month = Jun;}
  else if (tzDSTStartMonth = "Jul") {myDST.month = Jul;}
  else if (tzDSTStartMonth = "Aug") {myDST.month = Aug;}
  else if (tzDSTStartMonth = "Sep") {myDST.month = Sep;}
  else if (tzDSTStartMonth = "Oct") {myDST.month = Oct;}
  else if (tzDSTStartMonth = "Nov") {myDST.month = Nov;}
  else if (tzDSTStartMonth = "Dec") {myDST.month = Dec;}
  //myDST.month = Mar;

  myDST.hour = tzDSTStartTime;
  myDST.offset = tzDSTStartDiff;


Serial.println(tzDSTEndShortName);

  tzDSTEndShortName.toCharArray(buffer,5);
  strcpy(mySTD.abbrev, buffer);
  if (tzDSTEndDayNum = "First") {mySTD.week = First;}
  else if (tzDSTEndDayNum = "Second") {mySTD.week = Second;}
  else if (tzDSTEndDayNum = "Third") {mySTD.week = Third;}
  else if (tzDSTStartDayNum = "Fourth") {myDST.week = Fourth;}
  else if (tzDSTEndDayNum = "Last") {mySTD.week = Last;};
  //myCEST.week = Last;

  if (tzDSTEndDay = "Mon") {mySTD.dow = Mon;}
  else if (tzDSTEndDay = "Tue") {mySTD.dow = Tue;}
  else if (tzDSTEndDay = "Wed") {mySTD.dow = Wed;}
  else if (tzDSTEndDay = "Thu") {mySTD.dow = Thu;}
  else if (tzDSTEndDay = "Fri") {mySTD.dow = Fri;}
  else if (tzDSTEndDay = "Sat") {mySTD.dow = Sat;}
  else if (tzDSTEndDay = "Sun") {mySTD.dow = Sun;}
  //myDST.dow = Sun;

  if (tzDSTEndMonth = "Jan") {mySTD.month = Jan;}
  else if (tzDSTEndMonth = "Feb") {mySTD.month = Feb;}
  else if (tzDSTEndMonth = "Mar") {mySTD.month = Mar;}
  else if (tzDSTEndMonth = "Apr") {mySTD.month = Apr;}
  else if (tzDSTEndMonth = "May") {mySTD.month = May;}
  else if (tzDSTEndMonth = "Jun") {mySTD.month = Jun;}
  else if (tzDSTEndMonth = "Jul") {mySTD.month = Jul;}
  else if (tzDSTEndMonth = "Aug") {mySTD.month = Aug;}
  else if (tzDSTEndMonth = "Sep") {mySTD.month = Sep;}
  else if (tzDSTEndMonth = "Oct") {mySTD.month = Oct;}
  else if (tzDSTEndMonth = "Nov") {mySTD.month = Nov;}
  else if (tzDSTEndMonth = "Dec") {mySTD.month = Dec;}
  //myDST.month = Mar;

  mySTD.hour = tzDSTEndTime;
  mySTD.offset = tzDSTEndDiff;

  myTZ.setRules(myDST, mySTD);


}

Hi Again,

Forgot to say, this is the results that i get

1638898395
RTC Date/Time07/12/2021 17:33:15
1638901995
Local Date/Time07/12/2021 18:33:15 BST

Those are all assignments (=) and not comparisons (==).

Doh! yes, well i have now fixed all those and sorted out using time sync to sync the Arduino click with the RTC so i can use now().

I have added

TimeChangeRule myDST = {"BST", First, Sun, Mar, 2, 60};
TimeChangeRule mySTD = {"GMT", Last, Sun, Oct, 2, 0};

before the setRules and that now works, so its defiantly an issue with programmatically creating the TimeChangeRules. Does anyone have an example code i could use that creates valid TimeChangeRules?

Thanks
Ian...

Hi All,

Well i was right, it was me.

After doing a load more debugging last night and still not getting anywhere, i left it. Came back to it this morning and with a few more Serial.println statements i spotted it. When i split the TimeZoneRule form the input file I was not trim'ing the results so " Mar" was not equal to "Mar".

Fixed that and its all working fine now.

Regards,
Ian...