timezoned.rop.nl works incorrectly for Asia/Tehran, POSIX-style definition doesn't work either
setDebug(INFO);
waitForSync();
Serial.println("UTC: " + UTC.dateTime());
Timezone yourTZ;
yourTZ.setLocation(F("Asia/Tehran"));
Serial.print(F("Asia/Tehran: "));
Serial.println(yourTZ.dateTime());
The output is:
ezTime debug level set to INFO
Waiting for time sync
Querying pool.ntp.org ... success (round trip 28 ms)
Received time: Wednesday, 08-Apr-20 11:41:51.015 UTC
Time is in sync
UTC: Wednesday, 08-Apr-2020 11:41:51 UTC
Timezone lookup for: Asia/Tehran ... (round-trip 49 ms) success.
Olson: Asia/Tehran
Posix:
Asia/Tehran: Wednesday, 08-Apr-2020 11:41:51
If I set POSIX TZ definition to Tehran's (taken from my Kubuntu 19.10 machine, found in /usr/share/zoneinfo/Asia/Tehran), time is calculated incorrectly (DST not taken into account) -
Timezone myTZ;
Serial.println("\n----------------------");
myTZ.setPosix("<+0330>-3:30<+0430>,J79/24,J263/24");
Serial.print("Asia/Tehran: " + myTZ.getPosix());
Serial.println(" " + myTZ.dateTime());
This code prints out
----------------------
Asia/Tehran: <+0330>-3:30<+0430>,J79/24,J263/24 Wednesday, 08-Apr-2020 15:21:38 <+0330>
According to https://www.timeanddate.com/worldclock/iran/tehran , curent time in Tehran is 16:21:39 IRDT Wednesday, 8 April 2020
I could be wrong, but to me it looks like ezTime ignores DST rules defined with 'J'. From https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html :
Jn This specifies the Julian day, with n between 1 and 365. February 29 is never counted, even in leap years.
And the reason 'J' is used is probably this:
Iran operates Daylight saving Time between 1 Farvardin (March 21) and the 1 Mehr (September 23) when the time is 4.5 hours ahead of Greenwich Mean Time (GMT+4:30).
(from https://greenwichmeantime.com/time-zone/asia/iran/time-iran/ ) So, the days they switch to/from DST are fixed and can't be expressed with Mm.w.d
Oh wow... Eh, no, ezTime does not presently support Julian day Daylight Savings rules. So that's a real thing huh? It goes on the list of features to be added. I'm so sorry... (Damn, time has lots of weird exceptions. I was just celebrating that the Moroccans got rid of their "Let's have two DST periods a year!" thing so I didn't have to implement it...)
Would you consider lobbying your government to change this? I'm pretty sure lots of devices / IoT stuff / whatever doesn't do this either. You people must be setting a lot of clocks manually.
Well, yeah, except I'm not from Iran, I have just learned about this special case while trying to get Posix TZ strings for all Olsen time zone names out there :) I'm actually on the fence on whether I really need this or not. Most probably not, but i just hate leaving an unsolved problem in my code. So, if I actually happen to implement Julian day number in Posix DST rules, please consider merging.
I'd be happy to merge... :)
I have made the changes I think are necessary for DST start / end expressed in Julian days to work (both Jn and n - not taking and taking leap day into consideration), but I still can't convince myself (1) my changes are sufficient, they cover all cases and (2) I haven't broken anything within ezTime in the process. Tried to do some testing, but I'm not sure I correctly understand things like whether I'm setting current time correctly (if it's supposed to be in UTC or local time), etc.
Quite frankly, I'm stuck. Could you please take a look at my changes as the author of ezTime? Here's the gist containing two modified files, ezTime.h and ezTime.cpp.
Update: just to be clear - my modifications to POSIX TZ string parsing code in Timezone::tzTime() do work, and so does the new function I wrote ( makeJulianDayTime() ) to be called from Timezone::tzTime(). I have tested them with Asia/Tehran TZ string ("<+0330>-3:30<+0430>,J79/24,J263/24"), and it is parsed as intended, and current (+0430) time is calculated correctly by ezTime (checked current time in Tehran here).
The question is - will time be calculated correctly after the next DST transition on 21st of September, 2020, and after the next one, etc.