Aircoookie / WLED

Control WS2812B and many more types of digital RGB LEDs with an ESP8266 or ESP32 over WiFi!
https://kno.wled.ge
MIT License
14.79k stars 3.19k forks source link

Add all possible timezones #2193

Open cmtmc opened 3 years ago

cmtmc commented 3 years ago

Is your feature request related to a problem? Please describe. Timezones are not for all possible places and don't have number values. Help says "Your time zone. Open an issue if yours is unsupported."

Describe the solution you'd like Make it like Windows way - numbers and geolocations - from UTC-12:00 International Date Line West till UTC+14:00 Kiritimati island. Including utc-9:30, utc+9:30, utc+12:45.

blazoncek commented 3 years ago

Please provide a complete list and I'll do my best.

cmtmc commented 3 years ago

Official site - https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones

Sorted list - https://howtomanagedevices.com/windows-10/1774/list-of-windows-10-time-zone-codes-tzutil/

blazoncek commented 3 years ago

Both of these lists lack information on exact DST change.

cmtmc commented 3 years ago

https://en.wikipedia.org/wiki/Daylight_saving_time_by_country https://www.timeanddate.com/time/dst/2021.html - dates also differ

DST depends by country, not by timezone. Say Russia has 11 timezones - and "Observed DST in 1917–1919, 1921 (some areas), and 1981–2010. In 2011–2014, used permanent DST. In 2014, left permanent DST and switched to permanent standard time."

Not sure whether supporting DST is needed in WLED on regular basis.

Aircoookie commented 3 years ago

DST is the sole reason for timezones IMO, for regions with a year round standard time, googling [country] utc offset and putting that into the UTC offset field in the settings is a lot easier than even selecting the correct timezone from a dropdown menu.

Other than that, I would love to have support for every timezone. Windows tzutil /l lists 139, many of which are duplicates or "rare" time zones. While the time zone system in WLED was reworked to hardly use any RAM, of course we need flash, about 36 bytes per timezone for the dropdown entry and about 8 bytes for the timezone definition. That would mean around 6kB extra flash usage, something to consider. The effect of that would be lessened as soon as settings pages are gzip compressed (TODO).

I would support adding every distinct time zone, that is, every combination of UTC offsets and DST that are in actual use today. E.g. Japanese and Korean standard time is the same (UTC+9 year round), so I would regard them as one time zone.

blazoncek commented 3 years ago

If you want to have proper time controlled presets DST is essential. Otherwise we could simply use UTC +/- offset notation.

pbolduc commented 3 years ago

It is user friendly to support time zone names cause that is what people know. Never going to solve everyone's asks. Maybe 85%? Having extended UI (hidden by default) allow specify custom time zone, Standard Time Offset, Daylight Offset, and the parameters (1st/2nd/3rd, day of week, in month) would allow them to set any time zone settings. Better yet, would be nice if could pull the time zone from the internet (assume has internet access) for setting the parameters (browser CORS request?) so the settings are pulled and updated in UI and then posted to device? Changing time zones is something we will continue to chase, - https://data.iana.org/time-zones/tzdb/NEWS

Also addresses the issue when a location decides to stop following daylight savings time, like California, Oregon and Washington are. Allowing to override the presets allows these devices to continue to work with correct time zone settings without having to wait for a new WLED release.

cmtmc commented 3 years ago

It is user friendly to support time zone names cause that is what people know.

If the person finds WLED project, chooses power supply, purchases components, solders diode/capacitors/step-up controller, installs in needed place properly, recompiles using custom mods - I believe he can find out numeric value of his timezone.

Natal-CWB commented 3 years ago

It would be nice to have all timezones but it will consume a lot of precious memomry from ESP. Why not set UTC in hours? just add a 3600 multiplier to the code, because it's a little weird to put it in seconds. Just use UTC -3, UTC +13, UTC -6,5 instead of UTC-10800, UTC +46800, UTC -23400

blazoncek commented 3 years ago

Good point.

pbolduc commented 3 years ago

Edit: skip to my next comment, less complex and more extensible

The reason the time is set in seconds is because it is following unix timestamp format - https://www.unixtimestamp.com/ "This count starts at the Unix Epoch on January 1st, 1970 at UTC" Logically, I think WLED is only looking at the current time or short times in the future. There is no reason WLED needs to use the Unix Epoch. That could be shifted to WLED Epoch of Jan 1st, 2020. This only represents when "time began".

As for the problem of the time zone rules. The code uses this struct to capture the rules, requires 1 or 2 of these per time zone.

struct TimeChangeRule
{
    uint8_t week;      //First, Second, Third, Fourth, or Last week of the month
    uint8_t dow;       //day of week, 1=Sun, 2=Mon, ... 7=Sat
    uint8_t month;     //1=Jan, 2=Feb, ... 12=Dec
    uint8_t hour;      //0-23
    int16_t offset;        //offset from UTC in minutes
};

Based on the current time zones (https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) the offset needs to go from -12 to +14 hours. Not all time zones are full hours, some are 1/2 hour or 15/45 minutes. So storing the offset in minutes makes sense. If using bit packing and offset measured in multiples of 15 minutes, the size per time zone rule could go from 6 bytes down to 4 bytes

week:         0 -   4  =          3 bits
dow :         1 -   7  =          3 bits
mon :         1 -  12  =          4 bits
hr  :         0 -  23  =          5 bits
offset:    -720 - 840  =
     (15m)  -48 -  56  =         12 bits
                               ---------
                                 27 bits
                                  4 bytes

Based on my Googling, there are 38 time zones - https://www.timeanddate.com/time/current-number-time-zones.html

38 6 2 = 456 bytes for rules, not to mention the required markup in the HTML front end, that would be reduced to 304 bytes if using the bit packing. The UI stuff may be able be able to be packed if used javascript to render the list instead of hard coded html markup.

pbolduc commented 3 years ago

Just had another idea while having a shower, instead of all the complexity above, why dont we create a javascript file with all the data with all the rules, offsets, names, etc. This javascript file can be gz compressed in the same way the index page is. The settings page would fetch this javascript file to build it's UI dynamically. When saving the timezone, instead of passing back a "time zone id", the settings page would POST the rules for the currently selected time zone. This would allow us to remove the function updateTimezone() in ntp.cpp. The updateTimezone function it self takes up 908 bytes on esp32

image

pseudocode example timezones.js file

[ 
   { "name": "GMT/BST", 
     "dst":  {Last, Sun, Mar, 1, 60},
     "st": {Last, Sun, Oct, 2, 0} },
   { "name": "CET/CEST", 
     "dst":  {Last, Sun, Mar, 2, 120},
     "st": {Last, Sun, Oct, 3, 60} },

Could also store the list of time zones in a csv type file with extra column indicating the region. When generating the json file to be embedded there could be compiler flag to limit the time zones, something like below. This would allow supporting numerous time zones but also allow the option to reduce the memory usage by including only those time zones need for a particular install.

TZ_ALL TZ_NORTH_AMERICA TZ_SOUTH_AMERICA TZ_AFRICA TZ_EUROPE TZ_ASIA TZ_OCEANIC

softhack007 commented 1 year ago

@blazoncek is there anything left to do for this? If yes, we might be able to complement our TZ list in 0.14.1.

blazoncek commented 1 year ago

I given up on the idea of implementing this. Do what you think is ok.