Bug 1494160 - Modify timezone update script so that zones.json can contain recent and future rules; r=Fallen
This commit is contained in:
Родитель
0b95f178ee
Коммит
2308ad78d9
|
@ -480,3 +480,6 @@ pref.timezone.Asia.Atyrau=Asia/Atyrau
|
||||||
|
|
||||||
#added with 2.2017b
|
#added with 2.2017b
|
||||||
pref.timezone.America.Punta_Arenas=America/Punta Arenas
|
pref.timezone.America.Punta_Arenas=America/Punta Arenas
|
||||||
|
|
||||||
|
#added with 2.2018i
|
||||||
|
pref.timezone.Asia.Qostanay=Asia/Qostanay
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
const FEBRUARY = 1;
|
||||||
|
const OCTOBER = 9;
|
||||||
|
const NOVEMBER = 10;
|
||||||
|
|
||||||
|
const UTC_MINUS_3 = -3 * 3600;
|
||||||
|
const UTC_MINUS_2 = -2 * 3600;
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
do_calendar_startup(run_next_test);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This test requires timezone data going back to 2016. It's been kept here as an example.
|
||||||
|
/* add_test(function testCaracas() {
|
||||||
|
let time = cal.createDateTime();
|
||||||
|
let zone = cal.getTimezoneService().getTimezone("America/Caracas");
|
||||||
|
|
||||||
|
for (let month = JANUARY; month <= DECEMBER; month++) {
|
||||||
|
time.resetTo(2015, month, 1, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_430, time.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let month = JANUARY; month <= APRIL; month++) {
|
||||||
|
time.resetTo(2016, month, 1, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_430, time.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
time.resetTo(2016, MAY, 1, 1, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_430, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2016, MAY, 1, 3, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_4, time.toString());
|
||||||
|
|
||||||
|
for (let month = JUNE; month <= DECEMBER; month++) {
|
||||||
|
time.resetTo(2016, month, 1, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_4, time.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let month = JANUARY; month <= DECEMBER; month++) {
|
||||||
|
time.resetTo(2017, month, 1, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_4, time.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
}); */
|
||||||
|
|
||||||
|
// Brazil's rules are complicated. This tests every change in the time range we have data for.
|
||||||
|
add_test(function testSaoPaulo() {
|
||||||
|
let time = cal.createDateTime();
|
||||||
|
let zone = cal.getTimezoneService().getTimezone("America/Sao_Paulo");
|
||||||
|
|
||||||
|
time.resetTo(2018, FEBRUARY, 17, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2018, FEBRUARY, 18, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2018, NOVEMBER, 3, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2018, NOVEMBER, 4, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2019, FEBRUARY, 16, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2019, FEBRUARY, 17, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2019, NOVEMBER, 2, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2019, NOVEMBER, 3, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2020, FEBRUARY, 15, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2020, FEBRUARY, 16, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2020, OCTOBER, 31, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2020, NOVEMBER, 1, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2021, FEBRUARY, 20, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2021, FEBRUARY, 21, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2021, NOVEMBER, 6, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2021, NOVEMBER, 7, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2022, FEBRUARY, 19, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2022, FEBRUARY, 20, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2022, NOVEMBER, 5, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_3, time.toString());
|
||||||
|
|
||||||
|
time.resetTo(2022, NOVEMBER, 6, 0, 0, 0, zone);
|
||||||
|
equal(time.timezoneOffset, UTC_MINUS_2, time.toString());
|
||||||
|
|
||||||
|
run_next_test();
|
||||||
|
});
|
|
@ -49,6 +49,7 @@ skip-if = true # See bug 1481180. requesttimeoutfactor = 2
|
||||||
[test_startup_service.js]
|
[test_startup_service.js]
|
||||||
[test_storage.js]
|
[test_storage.js]
|
||||||
[test_timezone.js]
|
[test_timezone.js]
|
||||||
|
[test_timezone_changes.js]
|
||||||
[test_timezone_definition.js]
|
[test_timezone_definition.js]
|
||||||
[test_unifinder_utils.js]
|
[test_unifinder_utils.js]
|
||||||
[test_utils.js]
|
[test_utils.js]
|
||||||
|
|
|
@ -15,15 +15,22 @@ Otherwise manual corrections will get dropped when pushing the update.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
import argparse, ftplib, json, os, os.path, re, shutil, subprocess, sys, tarfile, tempfile
|
import argparse, ftplib, json, os, os.path, re, shutil, subprocess, sys, tarfile, tempfile
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from datetime import date, timedelta
|
||||||
|
|
||||||
|
# Keep timezone changes from this date onwards. If the zones.json file is becoming
|
||||||
|
# too large, consider changing to a later date.
|
||||||
|
HISTORY_CUTOFF = 20180101
|
||||||
|
FUTURE_CUTOFF = 20221231
|
||||||
|
|
||||||
|
|
||||||
class TimezoneUpdater(object):
|
class TimezoneUpdater(object):
|
||||||
""" Timezone updater class, use the run method to do everything automatically"""
|
""" Timezone updater class, use the run method to do everything automatically"""
|
||||||
def __init__(self, tzdata_path, zoneinfo_path, zoneinfo_pure_path):
|
def __init__(self, tzdata_path, zoneinfo_pure_path):
|
||||||
self.tzdata_path = tzdata_path
|
self.tzdata_path = tzdata_path
|
||||||
self.zoneinfo_path = zoneinfo_path
|
|
||||||
self.zoneinfo_pure_path = zoneinfo_pure_path
|
self.zoneinfo_pure_path = zoneinfo_pure_path
|
||||||
|
|
||||||
def download_tzdata(self):
|
def download_tzdata(self):
|
||||||
|
@ -55,14 +62,7 @@ class TimezoneUpdater(object):
|
||||||
def run_vzic(self, vzic_path):
|
def run_vzic(self, vzic_path):
|
||||||
"""Use vzic to create ICS versions of the data."""
|
"""Use vzic to create ICS versions of the data."""
|
||||||
|
|
||||||
# Use `vzic` to create 'pure' and 'non-pure' zone files.
|
# Use `vzic` to create zone files.
|
||||||
sys.stderr.write("Exporting zone info to %s\n" % self.zoneinfo_path)
|
|
||||||
subprocess.check_call([
|
|
||||||
vzic_path,
|
|
||||||
"--olson-dir", self.tzdata_path,
|
|
||||||
"--output-dir", self.zoneinfo_path
|
|
||||||
], stdout=sys.stderr)
|
|
||||||
|
|
||||||
sys.stderr.write("Exporting pure zone info to %s\n" % self.zoneinfo_pure_path)
|
sys.stderr.write("Exporting pure zone info to %s\n" % self.zoneinfo_pure_path)
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
vzic_path,
|
vzic_path,
|
||||||
|
@ -85,7 +85,7 @@ class TimezoneUpdater(object):
|
||||||
def read_zones_tab(self):
|
def read_zones_tab(self):
|
||||||
"""Read zones.tab for latitude and longitude data."""
|
"""Read zones.tab for latitude and longitude data."""
|
||||||
lat_long_data = {}
|
lat_long_data = {}
|
||||||
with open(os.path.join(self.zoneinfo_path, "zones.tab"), "r") as tab:
|
with open(os.path.join(self.zoneinfo_pure_path, "zones.tab"), "r") as tab:
|
||||||
for line in tab:
|
for line in tab:
|
||||||
if len(line) < 19:
|
if len(line) < 19:
|
||||||
sys.stderr.write("Line in zones.tab not long enough: %s\n" % line.strip())
|
sys.stderr.write("Line in zones.tab not long enough: %s\n" % line.strip())
|
||||||
|
@ -97,40 +97,137 @@ class TimezoneUpdater(object):
|
||||||
return lat_long_data
|
return lat_long_data
|
||||||
|
|
||||||
def read_ics(self, filename, lat_long_data):
|
def read_ics(self, filename, lat_long_data):
|
||||||
"""Read a single zone's ICS files.
|
"""Read a single zone's ICS files."""
|
||||||
|
|
||||||
We keep only the lines we want, and we use the pure version of RRULE if
|
|
||||||
the versions differ. See Asia/Jerusalem for an example."""
|
|
||||||
with open(os.path.join(self.zoneinfo_path, filename), "r") as zone:
|
|
||||||
zoneinfo = zone.readlines()
|
|
||||||
|
|
||||||
with open(os.path.join(self.zoneinfo_pure_path, filename), "r") as zone:
|
with open(os.path.join(self.zoneinfo_pure_path, filename), "r") as zone:
|
||||||
zoneinfo_pure = zone.readlines()
|
zoneinfo_pure = zone.readlines()
|
||||||
|
|
||||||
ics_data = []
|
# Loop through the lines of the file, splitting it into components.
|
||||||
for i in range(0, len(zoneinfo)):
|
components = []
|
||||||
line = zoneinfo[i]
|
current_component = None
|
||||||
key = line[:line.find(":")]
|
for i in range(0, len(zoneinfo_pure)):
|
||||||
|
line = zoneinfo_pure[i].rstrip()
|
||||||
|
[key, value] = line.split(":", 1)
|
||||||
|
|
||||||
if key == "BEGIN":
|
if line in ["BEGIN:STANDARD", "BEGIN:DAYLIGHT"]:
|
||||||
if line != "BEGIN:VCALENDAR\r\n":
|
current_component = {"line": i, "type": value}
|
||||||
ics_data.append(line)
|
|
||||||
elif key == "END":
|
elif line in ["END:STANDARD", "END:DAYLIGHT"]:
|
||||||
if line != "END:VCALENDAR\r\n":
|
components.append(current_component)
|
||||||
ics_data.append(line)
|
current_component = None
|
||||||
elif key in ("TZID", "TZOFFSETFROM", "TZOFFSETTO", "TZNAME", "DTSTART"):
|
|
||||||
ics_data.append(line)
|
elif current_component:
|
||||||
elif key == "RRULE":
|
if key == "RDATE":
|
||||||
if line == zoneinfo_pure[i]:
|
if "rdates" not in current_component:
|
||||||
ics_data.append(line)
|
current_component["rdates"] = []
|
||||||
|
current_component["rdates"].append(value)
|
||||||
else:
|
else:
|
||||||
sys.stderr.write("Using pure version of %s\n" % filename[:-4])
|
current_component[key] = value
|
||||||
ics_data.append(zoneinfo_pure[i])
|
|
||||||
|
# Create a copy of each component for every date that it started.
|
||||||
|
# Later, we'll sort them into order of starting date.
|
||||||
|
components_by_start_date = {}
|
||||||
|
for component in components:
|
||||||
|
max_rdate = int(component["DTSTART"][0:8])
|
||||||
|
components_by_start_date[max_rdate] = component
|
||||||
|
if "rdates" in component:
|
||||||
|
for rdate in component["rdates"]:
|
||||||
|
rdate = int(rdate[0:8])
|
||||||
|
max_rdate = max(rdate, max_rdate)
|
||||||
|
components_by_start_date[rdate] = component
|
||||||
|
component["valid_rdates"] = filter(
|
||||||
|
lambda rd: FUTURE_CUTOFF >= int(rd[0:8]) >= HISTORY_CUTOFF,
|
||||||
|
component["rdates"]
|
||||||
|
)
|
||||||
|
component["max_date"] = max_rdate
|
||||||
|
|
||||||
|
# Sort, and keep only the components in use since the cutoff date.
|
||||||
|
kept_components = []
|
||||||
|
finished = False
|
||||||
|
for key in sorted(components_by_start_date.keys(), reverse=True):
|
||||||
|
if key > FUTURE_CUTOFF:
|
||||||
|
continue
|
||||||
|
component = components_by_start_date[key]
|
||||||
|
if finished and "RRULE" not in component:
|
||||||
|
continue
|
||||||
|
if "used" in component:
|
||||||
|
continue
|
||||||
|
component["used"] = True
|
||||||
|
kept_components.append(component)
|
||||||
|
if key <= HISTORY_CUTOFF:
|
||||||
|
finished = True
|
||||||
|
|
||||||
|
for i in range(len(kept_components)):
|
||||||
|
component = kept_components[i]
|
||||||
|
last = i == len(kept_components) - 1
|
||||||
|
# In this block of code, we attempt to match what vzic does when
|
||||||
|
# creating "Outlook-compatible" timezone files. This is to minimise
|
||||||
|
# changes in our zones.json file. And to be more Outlook-compatible.
|
||||||
|
if int(component["DTSTART"][0:8]) < HISTORY_CUTOFF:
|
||||||
|
if not last and "valid_rdates" in component and len(component["valid_rdates"]) > 0:
|
||||||
|
component["DTSTART"] = component["valid_rdates"][0]
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Change the start date to what it would've been in 1970.
|
||||||
|
start_date = "19700101"
|
||||||
|
start_time = "T000000"
|
||||||
|
|
||||||
|
if "RRULE" in component:
|
||||||
|
rrule = dict(part.split("=") for part in component["RRULE"].split(";"))
|
||||||
|
bymonth = int(rrule["BYMONTH"])
|
||||||
|
weekday = rrule["BYDAY"].lstrip("-012345")
|
||||||
|
weekday_index = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"].index(weekday)
|
||||||
|
|
||||||
|
if "BYMONTHDAY" in rrule:
|
||||||
|
bymonthday = list(int(d) for d in rrule["BYMONTHDAY"].split(","))
|
||||||
|
for day in bymonthday:
|
||||||
|
test_day = date(1970, bymonth, day)
|
||||||
|
if test_day.weekday() == weekday_index:
|
||||||
|
start_date = test_day.strftime("%Y%m%d")
|
||||||
|
start_time = component["DTSTART"][8:]
|
||||||
|
break
|
||||||
|
elif "BYDAY" in rrule:
|
||||||
|
which_weekday = int(rrule["BYDAY"].rstrip("AEFHMORSTUW"))
|
||||||
|
days_matching = [0]
|
||||||
|
test_day = date(1970, bymonth, 1)
|
||||||
|
while test_day.month == bymonth:
|
||||||
|
if test_day.weekday() == weekday_index:
|
||||||
|
days_matching.append(test_day)
|
||||||
|
test_day = test_day + timedelta(days=1)
|
||||||
|
start_date = days_matching[which_weekday].strftime("%Y%m%d")
|
||||||
|
start_time = component["DTSTART"][8:]
|
||||||
|
|
||||||
|
component["DTSTART"] = start_date + start_time
|
||||||
|
|
||||||
|
# Sort the components back into the order they appeared in the original file.
|
||||||
|
# This is to minimise changes in our zones.json file.
|
||||||
|
kept_components.sort(key=lambda b: b["line"])
|
||||||
|
|
||||||
|
zone_name = filename[:-4]
|
||||||
|
ics = []
|
||||||
|
for component in kept_components:
|
||||||
|
ics_lines = []
|
||||||
|
ics_lines.append("BEGIN:%s" % component["type"])
|
||||||
|
if len(kept_components) == 1 or len(component["TZOFFSETFROM"]) != 5:
|
||||||
|
ics_lines.append("TZOFFSETFROM:%s" % component["TZOFFSETTO"])
|
||||||
|
else:
|
||||||
|
ics_lines.append("TZOFFSETFROM:%s" % component["TZOFFSETFROM"])
|
||||||
|
ics_lines.append("TZOFFSETTO:%s" % component["TZOFFSETTO"])
|
||||||
|
|
||||||
|
if "TZNAME" in component:
|
||||||
|
ics_lines.append("TZNAME:%s" % component["TZNAME"])
|
||||||
|
ics_lines.append("DTSTART:%s" % component["DTSTART"])
|
||||||
|
if "RRULE" in component:
|
||||||
|
ics_lines.append("RRULE:%s" % component["RRULE"])
|
||||||
|
elif len(kept_components) > 1 and "valid_rdates" in component:
|
||||||
|
for rdate in component["valid_rdates"]:
|
||||||
|
ics_lines.append("RDATE:%s" % rdate)
|
||||||
|
|
||||||
|
ics_lines.append("END:%s" % component["type"])
|
||||||
|
ics.append("\r\n".join(ics_lines))
|
||||||
|
|
||||||
zone_data = {
|
zone_data = {
|
||||||
"ics": "".join(ics_data).rstrip()
|
"ics": ics,
|
||||||
}
|
}
|
||||||
zone_name = filename[:-4]
|
|
||||||
if zone_name in lat_long_data:
|
if zone_name in lat_long_data:
|
||||||
zone_data["latitude"] = lat_long_data[zone_name][0]
|
zone_data["latitude"] = lat_long_data[zone_name][0]
|
||||||
zone_data["longitude"] = lat_long_data[zone_name][1]
|
zone_data["longitude"] = lat_long_data[zone_name][1]
|
||||||
|
@ -144,6 +241,8 @@ class TimezoneUpdater(object):
|
||||||
|
|
||||||
zones = {}
|
zones = {}
|
||||||
for entry in os.listdir(path):
|
for entry in os.listdir(path):
|
||||||
|
if entry == "Etc":
|
||||||
|
continue
|
||||||
fullpath = os.path.join(path, entry)
|
fullpath = os.path.join(path, entry)
|
||||||
if os.path.isdir(fullpath):
|
if os.path.isdir(fullpath):
|
||||||
zones.update(self.read_dir(fullpath, process_zone, os.path.join(prefix, entry)))
|
zones.update(self.read_dir(fullpath, process_zone, os.path.join(prefix, entry)))
|
||||||
|
@ -219,7 +318,7 @@ class TimezoneUpdater(object):
|
||||||
self.run_vzic(vzic_path)
|
self.run_vzic(vzic_path)
|
||||||
lat_long_data = self.read_zones_tab()
|
lat_long_data = self.read_zones_tab()
|
||||||
|
|
||||||
newzones = self.read_dir(self.zoneinfo_path,
|
newzones = self.read_dir(self.zoneinfo_pure_path,
|
||||||
lambda fn: self.read_ics(fn, lat_long_data))
|
lambda fn: self.read_ics(fn, lat_long_data))
|
||||||
|
|
||||||
newaliases = self.link_removed_zones(zonesjson["zones"], newzones, links)
|
newaliases = self.link_removed_zones(zonesjson["zones"], newzones, links)
|
||||||
|
@ -307,21 +406,13 @@ def main():
|
||||||
# A test data update must occur before the zones.json file gets updated to have meaningful data
|
# A test data update must occur before the zones.json file gets updated to have meaningful data
|
||||||
create_test_data(json_file)
|
create_test_data(json_file)
|
||||||
|
|
||||||
zoneinfo_path = tempfile.mkdtemp(prefix="zones")
|
|
||||||
zoneinfo_pure_path = tempfile.mkdtemp(prefix="zones")
|
zoneinfo_pure_path = tempfile.mkdtemp(prefix="zones")
|
||||||
|
|
||||||
updater = TimezoneUpdater(args.tzdata_path, zoneinfo_path, zoneinfo_pure_path)
|
updater = TimezoneUpdater(args.tzdata_path, zoneinfo_pure_path)
|
||||||
updater.run(json_file, tzprops_file, args.vzic_path)
|
updater.run(json_file, tzprops_file, args.vzic_path)
|
||||||
|
|
||||||
# Clean up.
|
# Clean up.
|
||||||
shutil.rmtree(zoneinfo_path)
|
|
||||||
shutil.rmtree(zoneinfo_pure_path)
|
shutil.rmtree(zoneinfo_pure_path)
|
||||||
|
|
||||||
print """
|
|
||||||
When updating timezone definitions, please check the zones America/Campo_Grande,
|
|
||||||
America/Cuiaba, and America/Sao_Paulo are not reset to their previous buggy state.
|
|
||||||
See bug 1515937 for more information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -498,7 +498,12 @@
|
||||||
},
|
},
|
||||||
"Africa/Casablanca": {
|
"Africa/Casablanca": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20180325T020000\r\nRDATE:20180325T020000\r\nRDATE:20180617T020000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:20180513T030000\r\nRDATE:20180513T030000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20190609T020000\r\nRDATE:20190609T020000\r\nRDATE:20200524T020000\r\nRDATE:20210516T020000\r\nRDATE:20220508T020000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20181028T030000\r\nRDATE:20181028T030000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:20190505T030000\r\nRDATE:20190505T030000\r\nRDATE:20200419T030000\r\nRDATE:20210411T030000\r\nRDATE:20220327T030000\r\nEND:DAYLIGHT"
|
||||||
],
|
],
|
||||||
"latitude": "+0333900",
|
"latitude": "+0333900",
|
||||||
"longitude": "-0073500"
|
"longitude": "-0073500"
|
||||||
|
@ -548,7 +553,12 @@
|
||||||
},
|
},
|
||||||
"Africa/El_Aaiun": {
|
"Africa/El_Aaiun": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0100\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20180325T020000\r\nRDATE:20180325T020000\r\nRDATE:20180617T020000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:20180513T030000\r\nRDATE:20180513T030000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20181028T030000\r\nRDATE:20181028T030000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0000\r\nTZNAME:+00\r\nDTSTART:20190505T030000\r\nRDATE:20190505T030000\r\nRDATE:20200419T030000\r\nRDATE:20210411T030000\r\nRDATE:20220327T030000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0100\r\nTZNAME:+01\r\nDTSTART:20190609T020000\r\nRDATE:20190609T020000\r\nRDATE:20200524T020000\r\nRDATE:20210516T020000\r\nRDATE:20220508T020000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0270900",
|
"latitude": "+0270900",
|
||||||
"longitude": "-0131200"
|
"longitude": "-0131200"
|
||||||
|
@ -744,7 +754,8 @@
|
||||||
},
|
},
|
||||||
"Africa/Sao_Tome": {
|
"Africa/Sao_Tome": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0000\r\nTZNAME:GMT\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0000\r\nTZOFFSETTO:+0100\r\nTZNAME:WAT\r\nDTSTART:20180101T010000\r\nRDATE:20180101T010000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0000\r\nTZNAME:GMT\r\nDTSTART:20190101T020000\r\nRDATE:20190101T020000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0002000",
|
"latitude": "+0002000",
|
||||||
"longitude": "+0064400"
|
"longitude": "+0064400"
|
||||||
|
@ -988,8 +999,10 @@
|
||||||
},
|
},
|
||||||
"America/Campo_Grande": {
|
"America/Campo_Grande": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19701101T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20181104T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:19700215T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=3SU\r\nEND:STANDARD"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19700101T000000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20180218T000000\r\nRDATE:20180218T000000\r\nRDATE:20190217T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20200216T000000\r\nRDATE:20200216T000000\r\nRDATE:20210221T000000\r\nRDATE:20220220T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0202700",
|
"latitude": "-0202700",
|
||||||
"longitude": "-0543700"
|
"longitude": "-0543700"
|
||||||
|
@ -1054,8 +1067,10 @@
|
||||||
},
|
},
|
||||||
"America/Cuiaba": {
|
"America/Cuiaba": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19701101T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20181104T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:19700215T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=3SU\r\nEND:STANDARD"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19700101T000000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20180218T000000\r\nRDATE:20180218T000000\r\nRDATE:20190217T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20200216T000000\r\nRDATE:20200216T000000\r\nRDATE:20210221T000000\r\nRDATE:20220220T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0153500",
|
"latitude": "-0153500",
|
||||||
"longitude": "-0560500"
|
"longitude": "-0560500"
|
||||||
|
@ -1174,8 +1189,10 @@
|
||||||
},
|
},
|
||||||
"America/Grand_Turk": {
|
"America/Grand_Turk": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0500\r\nTZNAME:EST\r\nDTSTART:19701101T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:STANDARD",
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0500\r\nTZNAME:EST\r\nDTSTART:20181104T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:STANDARD",
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nTZNAME:EDT\r\nDTSTART:19700308T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nEND:DAYLIGHT"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nTZNAME:EDT\r\nDTSTART:20190310T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0400\r\nTZNAME:AST\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0400\r\nTZNAME:EDT\r\nDTSTART:20180311T020000\r\nRDATE:20180311T020000\r\nEND:DAYLIGHT"
|
||||||
],
|
],
|
||||||
"latitude": "+0212800",
|
"latitude": "+0212800",
|
||||||
"longitude": "-0710800"
|
"longitude": "-0710800"
|
||||||
|
@ -1454,8 +1471,12 @@
|
||||||
},
|
},
|
||||||
"America/Metlakatla": {
|
"America/Metlakatla": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0800\r\nTZOFFSETTO:-0900\r\nTZNAME:AKST\r\nDTSTART:19701101T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:STANDARD",
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0800\r\nTZOFFSETTO:-0900\r\nTZNAME:AKST\r\nDTSTART:20191103T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:STANDARD",
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0900\r\nTZOFFSETTO:-0800\r\nTZNAME:AKDT\r\nDTSTART:19700308T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nEND:DAYLIGHT"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0900\r\nTZOFFSETTO:-0800\r\nTZNAME:AKDT\r\nDTSTART:20200308T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0800\r\nTZOFFSETTO:-0800\r\nTZNAME:PST\r\nDTSTART:20181104T020000\r\nRDATE:20181104T020000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0800\r\nTZOFFSETTO:-0900\r\nTZNAME:AKST\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0900\r\nTZOFFSETTO:-0800\r\nTZNAME:AKDT\r\nDTSTART:20180311T020000\r\nRDATE:20180311T020000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0800\r\nTZOFFSETTO:-0800\r\nTZNAME:AKDT\r\nDTSTART:20190310T020000\r\nRDATE:20190310T020000\r\nEND:DAYLIGHT"
|
||||||
],
|
],
|
||||||
"latitude": "+0550737",
|
"latitude": "+0550737",
|
||||||
"longitude": "-1313435"
|
"longitude": "-1313435"
|
||||||
|
@ -1696,8 +1717,11 @@
|
||||||
},
|
},
|
||||||
"America/Santiago": {
|
"America/Santiago": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:19700405T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=2,3,4,5,6,7,8;BYDAY=SU\r\nEND:STANDARD",
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20190407T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=2,3,4,5,6,7,8;BYDAY=SU\r\nEND:STANDARD",
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19700906T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=9;BYMONTHDAY=2,3,4,5,6,7,8;BYDAY=SU\r\nEND:DAYLIGHT"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20190908T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=9;BYMONTHDAY=2,3,4,5,6,7,8;BYDAY=SU\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0400\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20180812T000000\r\nRDATE:20180812T000000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0400\r\nTZNAME:-04\r\nDTSTART:20180513T000000\r\nRDATE:20180513T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0332700",
|
"latitude": "-0332700",
|
||||||
"longitude": "-0704000"
|
"longitude": "-0704000"
|
||||||
|
@ -1711,8 +1735,10 @@
|
||||||
},
|
},
|
||||||
"America/Sao_Paulo": {
|
"America/Sao_Paulo": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0200\r\nTZNAME:-02\r\nDTSTART:19701101T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0200\r\nTZNAME:-02\r\nDTSTART:20181104T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nEND:DAYLIGHT",
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0200\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:19700215T000000\r\nRRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=3SU\r\nEND:STANDARD"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0200\r\nTZNAME:-02\r\nDTSTART:19700101T000000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0200\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20180218T000000\r\nRDATE:20180218T000000\r\nRDATE:20190217T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0300\r\nTZOFFSETTO:-0300\r\nTZNAME:-03\r\nDTSTART:20200216T000000\r\nRDATE:20200216T000000\r\nRDATE:20210221T000000\r\nRDATE:20220220T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0233200",
|
"latitude": "-0233200",
|
||||||
"longitude": "-0463700"
|
"longitude": "-0463700"
|
||||||
|
@ -1871,7 +1897,8 @@
|
||||||
},
|
},
|
||||||
"Antarctica/Casey": {
|
"Antarctica/Casey": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0800\r\nTZOFFSETTO:+0800\r\nTZNAME:+08\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0800\r\nTZOFFSETTO:+1100\r\nTZNAME:+11\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+1100\r\nTZOFFSETTO:+0800\r\nTZNAME:+08\r\nDTSTART:20180311T040000\r\nRDATE:20180311T040000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0661700",
|
"latitude": "-0661700",
|
||||||
"longitude": "+1103100"
|
"longitude": "+1103100"
|
||||||
|
@ -2130,7 +2157,7 @@
|
||||||
"Asia/Famagusta": {
|
"Asia/Famagusta": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0300\r\nTZOFFSETTO:+0200\r\nTZNAME:EET\r\nDTSTART:19701025T040000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD",
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0300\r\nTZOFFSETTO:+0200\r\nTZNAME:EET\r\nDTSTART:19701025T040000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD",
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0300\r\nTZNAME:EEST\r\nDTSTART:19700329T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0300\r\nTZNAME:EEST\r\nDTSTART:20180325T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT"
|
||||||
],
|
],
|
||||||
"latitude": "+0350700",
|
"latitude": "+0350700",
|
||||||
"longitude": "+0335700"
|
"longitude": "+0335700"
|
||||||
|
@ -2365,7 +2392,8 @@
|
||||||
},
|
},
|
||||||
"Asia/Pyongyang": {
|
"Asia/Pyongyang": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0900\r\nTZOFFSETTO:+0900\r\nTZNAME:KST\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0900\r\nTZOFFSETTO:+0830\r\nTZNAME:KST\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0830\r\nTZOFFSETTO:+0900\r\nTZNAME:KST\r\nDTSTART:20180504T233000\r\nRDATE:20180504T233000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0390100",
|
"latitude": "+0390100",
|
||||||
"longitude": "+1254500"
|
"longitude": "+1254500"
|
||||||
|
@ -2386,7 +2414,8 @@
|
||||||
},
|
},
|
||||||
"Asia/Qyzylorda": {
|
"Asia/Qyzylorda": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0500\r\nTZOFFSETTO:+0500\r\nTZNAME:+05\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0600\r\nTZOFFSETTO:+0600\r\nTZNAME:+06\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0600\r\nTZOFFSETTO:+0500\r\nTZNAME:+05\r\nDTSTART:20181221T000000\r\nRDATE:20181221T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0444800",
|
"latitude": "+0444800",
|
||||||
"longitude": "+0652800"
|
"longitude": "+0652800"
|
||||||
|
@ -2463,7 +2492,9 @@
|
||||||
},
|
},
|
||||||
"Asia/Tehran": {
|
"Asia/Tehran": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0330\r\nTZOFFSETTO:+0330\r\nTZNAME:+0330\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0400\r\nTZOFFSETTO:+0330\r\nTZNAME:+0330\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0330\r\nTZOFFSETTO:+0430\r\nTZNAME:+0430\r\nDTSTART:20180321T235959\r\nRDATE:20180321T235959\r\nRDATE:20190321T235959\r\nRDATE:20200320T235959\r\nRDATE:20210321T235959\r\nRDATE:20220321T235959\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0430\r\nTZOFFSETTO:+0330\r\nTZNAME:+0330\r\nDTSTART:20180921T235959\r\nRDATE:20180921T235959\r\nRDATE:20190921T235959\r\nRDATE:20200920T235959\r\nRDATE:20210921T235959\r\nRDATE:20220921T235959\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0354000",
|
"latitude": "+0354000",
|
||||||
"longitude": "+0512600"
|
"longitude": "+0512600"
|
||||||
|
@ -3158,7 +3189,8 @@
|
||||||
},
|
},
|
||||||
"Europe/Volgograd": {
|
"Europe/Volgograd": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0400\r\nTZOFFSETTO:+0400\r\nTZNAME:+04\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0300\r\nTZOFFSETTO:+0400\r\nTZNAME:+04\r\nDTSTART:20181028T020000\r\nRDATE:20181028T020000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:+0400\r\nTZOFFSETTO:+0300\r\nTZNAME:+03\r\nDTSTART:19700101T000000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "+0484400",
|
"latitude": "+0484400",
|
||||||
"longitude": "+0442500"
|
"longitude": "+0442500"
|
||||||
|
@ -3312,8 +3344,11 @@
|
||||||
},
|
},
|
||||||
"Pacific/Easter": {
|
"Pacific/Easter": {
|
||||||
"ics": [
|
"ics": [
|
||||||
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0600\r\nTZNAME:-06\r\nDTSTART:19700404T220000\r\nRRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SA\r\nEND:STANDARD",
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0600\r\nTZNAME:-06\r\nDTSTART:20190406T220000\r\nRRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SA\r\nEND:STANDARD",
|
||||||
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0500\r\nTZNAME:-05\r\nDTSTART:19700905T220000\r\nRRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=1SA\r\nEND:DAYLIGHT"
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0500\r\nTZNAME:-05\r\nDTSTART:20190907T220000\r\nRRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=1SA\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0600\r\nTZNAME:-06\r\nDTSTART:19700101T000000\r\nEND:STANDARD",
|
||||||
|
"BEGIN:DAYLIGHT\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0500\r\nTZNAME:-05\r\nDTSTART:20180811T220000\r\nRDATE:20180811T220000\r\nEND:DAYLIGHT",
|
||||||
|
"BEGIN:STANDARD\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0600\r\nTZNAME:-06\r\nDTSTART:20180512T220000\r\nRDATE:20180512T220000\r\nEND:STANDARD"
|
||||||
],
|
],
|
||||||
"latitude": "-0270900",
|
"latitude": "-0270900",
|
||||||
"longitude": "-1092600"
|
"longitude": "-1092600"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче