2020-06-02 06:07 AM
To enable/Disable the Daylight Savings to either plus minus or none, whats the most efficient way to do this?
I have written a routine that checks for the last Sunday in March and October (I'm UK, not sure if its the same all over?), but it seems horrendously overkill, is there a quicker way to do this? surely?
2020-06-02 07:06 AM
> I'm UK, not sure if its the same all over?
No, it's not, the rules vary worldwide. UK supposedly still uses the common EU rule, (and DST will be abandoned within two or three years in the EU, btw.). USA uses a different rule, and there are s handful of yet another rules worldwide.
> is there a quicker way to do this
No. Time is a notorious PITA.
JW
2020-06-02 07:12 AM
The impression I get from the Wikipedia page is that it is arbitrary (decided by the government).
The dates on which clocks change vary with location and year; consequently, the time differences between regions also vary throughout the year.
And from what I read, Europe has voted to abolish time changes (although individual countries may decide if they are permanently in European summer time or winter time). https://www.bbc.co.uk/news/world-europe-47704345
So I don't think you can rely on a rule, no matter how complex.
Hope this helps,
Danish
2020-06-02 08:00 AM
Of course it is not the same all over. Think about it, people down under must have it the other way round.
There is support for DST in newlib, only the timezone database is missing, because a full database would be way too big for your average embedded system (3.5 MB on my Linux PC). It can at least determine if DST was/is/will be in effect in a specified region at a specific time, when the correct rule is supplied.
#define _POSIX_C_SOURCE 200809
#include <stdlib.h>
#include <time.h>
volatile struct tm a, b;
volatile time_t r;
void datetest(void) {
a.tm_year = 120; // 1900 + 120 = 2020
a.tm_mon = 0; // Jan = 0
a.tm_mday = 1;
a.tm_hour = 13;
a.tm_min = 1;
a.tm_sec = 1;
b = a;
setenv("TZ", "NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0", 1); // current(?) rule for NZ
tzset();
r = mktime((struct tm *)&b);
while(1) // b.tm_isdst is now 1, DST was in effect on 01.01.2020 in NZ
__NOP();
}
The rule string is lifted from man tzset.
Now you still have a few problems. You need a rule for every region where your product is going to be used.
You certainly won't need the full 3.5 MB database, apart from the obvious problem with its size it contains a lot of unnecessary information, because it goes all the way back to the 19th century. However I could not find a trivial way to extract the present day rules from it. The code in this thread migh help if you haven't given it up yet. If you manage to extract a present day ruleset from a full zoneinfo database, it would fit in maybe 20 kB.
Then you need updates whenever the rule set changes in the future. It is controlled by politics, so expect a lot of stupidity around the issue. Europe is planning to abandon DST in a year or two, several (most?) of its countries are going to repeat the mistake that Russia has made recently, they went to round-the-year DST in 2014, then regretted it and went to round-the-year winter time in 2015, so two updates for every piece of equipment that keeps the date, in the country with the most timezones in the world.
2020-06-02 10:20 AM
Most efficient way is to let the user adjust the clock.