Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
tails
thunderbird
Commits
a783ae47
Commit
a783ae47
authored
Oct 23, 2021
by
Carsten Schoenert
Browse files
Update upstream source from tag 'upstream/91.2.1'
Update to upstream version '91.2.1' with Debian dir 3c553fb984f900318108e93e9cc4223bcf2a8e64
parents
bcb56777
12a433a7
Changes
641
Hide whitespace changes
Inline
Side-by-side
comm/calendar/base/content/imip-bar.js
View file @
a783ae47
...
...
@@ -398,6 +398,9 @@ var calImipBar = {
* @returns {Boolean} true, if the action succeeded
*/
executeAction
(
aParticipantStatus
,
aResponse
)
{
// control to avoid processing _execAction on later user changes on the item
let
isFirstProcessing
=
true
;
/**
* Internal function to trigger an scheduling operation
*
...
...
@@ -425,6 +428,7 @@ var calImipBar = {
let
opListener
=
{
QueryInterface
:
ChromeUtils
.
generateQI
([
"
calIOperationListener
"
]),
onOperationComplete
(
aCalendar
,
aStatus
,
aOperationType
,
aId
,
aDetail
)
{
isFirstProcessing
=
false
;
if
(
Components
.
isSuccessCode
(
aStatus
)
&&
isDeclineCounter
)
{
// TODO: move the DECLINECOUNTER stuff to actionFunc
aItipItem
.
getItemList
().
forEach
(
aItem
=>
{
...
...
@@ -574,8 +578,6 @@ var calImipBar = {
if
(
saveitems
.
length
>
0
)
{
let
methods
=
{
receivedMethod
:
"
PUBLISH
"
,
responseMethod
:
"
PUBLISH
"
};
let
newItipItem
=
cal
.
itip
.
getModifiedItipItem
(
calImipBar
.
itipItem
,
saveitems
,
methods
);
// control to avoid processing _execAction on later user changes on the item
let
isFirstProcessing
=
true
;
// setup callback and trigger re-processing
let
storeCopy
=
function
(
aItipItem
,
aRc
,
aActionFunc
,
aFoundItems
)
{
if
(
isFirstProcessing
&&
aActionFunc
&&
Components
.
isSuccessCode
(
aRc
))
{
...
...
@@ -583,7 +585,6 @@ var calImipBar = {
}
};
cal
.
itip
.
processItipItem
(
newItipItem
,
storeCopy
);
isFirstProcessing
=
false
;
}
// we stop here to not process the original item
return
false
;
...
...
comm/calendar/base/modules/utils/calPrintUtils.jsm
View file @
a783ae47
...
...
@@ -21,6 +21,8 @@ ChromeUtils.defineModuleGetter(this, "cal", "resource:///modules/calendar/calUti
const EXPORTED_SYMBOLS = ["calprint"]; /* exported calprint */
const weekInfoService = cal.getWeekInfoService();
var calprint = {
ensureInitialized() {
// Deliberate no-op. By calling this function from outside, you've ensured
...
...
@@ -49,17 +51,15 @@ var calprint = {
}
document.getElementById("tasks-list-box").hidden = true;
let items = await getItems(startDate, endDate, filter, notDueTasks);
switch (type) {
case "list":
await listView.draw(document,
item
s);
await listView.draw(document,
startDate, endDate, filter, notDueTask
s);
break;
case "monthGrid":
await monthGridView.draw(document, startDate, endDate,
item
s);
await monthGridView.draw(document, startDate, endDate,
filter, notDueTask
s);
break;
case "weekPlanner":
await weekPlannerView.draw(document, startDate, endDate,
item
s);
await weekPlannerView.draw(document, startDate, endDate,
filter, notDueTask
s);
break;
}
},
...
...
@@ -226,12 +226,26 @@ function getItems(startDate, endDate, filter, notDueTasks) {
});
}
/**
* A simple list of calendar items.
*/
let listView = {
async draw(document, items) {
/**
* Create the list view.
*
* @param {HTMLDocument} document
* @param {calIDateTime} startDate - the first day of the months to be displayed
* @param {calIDateTime} endDate - the first day of the month AFTER the
* months to be displayed
* @param {integer} filter - calICalendar ITEM_FILTER flags
* @param {boolean} notDueTasks - if true, include tasks with no due date
*/
async draw(document, startDate, endDate, filter, notDueTasks) {
let container = document.getElementById("list-container");
let listItemTemplate = document.getElementById("list-item-template");
// Sort items.
// Get and sort items.
let items = await getItems(startDate, endDate, filter, notDueTasks);
items.sort((a, b) => {
let start_a = a[cal.dtz.startDateProp(a)];
if (!start_a) {
...
...
@@ -244,6 +258,7 @@ let listView = {
return start_a.compare(start_b);
});
// Display the items.
for (let item of items) {
let itemNode = listItemTemplate.content.firstElementChild.cloneNode(true);
...
...
@@ -264,16 +279,16 @@ let listView = {
}
};
let
s
tartDate = item[cal.dtz.startDateProp(item)];
let
e
ndDate = item[cal.dtz.endDateProp(item)];
if (
s
tartDate ||
e
ndDate) {
let
itemS
tartDate = item[cal.dtz.startDateProp(item)];
let
itemE
ndDate = item[cal.dtz.endDateProp(item)];
if (
itemS
tartDate ||
itemE
ndDate) {
// This is a task with a start or due date, format accordingly
let prefixWhen = cal.l10n.getCalString("htmlPrefixWhen");
itemNode.querySelector(".intervalkey").textContent = prefixWhen;
let startNode = itemNode.querySelector(".dtstart");
let dateString = cal.dtz.formatter.formatItemInterval(item);
startNode.setAttribute("title",
s
tartDate ?
s
tartDate.icalString : "none");
startNode.setAttribute("title",
itemS
tartDate ?
itemS
tartDate.icalString : "none");
startNode.textContent = dateString;
} else {
let row = itemNode.querySelector(".intervalrow");
...
...
@@ -297,25 +312,58 @@ let listView = {
container.appendChild(itemNode);
}
// Set the page title.
let startMonth = cal.l10n.formatMonth(startDate.month + 1, "calendar", "monthInYear");
let startMonthTitle = cal.l10n.getCalString("monthInYear", [startMonth, startDate.year]);
endDate.day--;
let endMonth = cal.l10n.formatMonth(endDate.month + 1, "calendar", "monthInYear");
let endMonthTitle = cal.l10n.getCalString("monthInYear", [endMonth, endDate.year]);
if (startMonthTitle == endMonthTitle) {
document.title = startMonthTitle;
} else {
document.title = `${startMonthTitle} – ${endMonthTitle}`;
}
},
};
/**
* A layout with one calendar month per page.
*/
let monthGridView = {
dayTable: {},
async draw(document, start, end, items) {
let startDate = this.normalizeStartDate(start);
let endDate = this.normalizeEndDate(end);
/**
* Create the month grid view.
*
* @param {HTMLDocument} document
* @param {calIDateTime} startDate - the first day of the months to be displayed
* @param {calIDateTime} endDate - the first day of the month AFTER the
* months to be displayed
* @param {integer} filter - calICalendar ITEM_FILTER flags
* @param {boolean} notDueTasks - if true, include tasks with no due date
*/
async draw(document, startDate, endDate, filter, notDueTasks) {
let container = document.getElementById("month-container");
//
Now set up all the months we need to
//
Draw the month grid(s).
let current = startDate.clone();
do {
container.appendChild(this.drawMonth(document, current));
current.month += 1;
} while (current.compare(endDate) <
=
0);
} while (current.compare(endDate) < 0);
// Extend the date range to include adjacent days that will be printed.
startDate = weekInfoService.getStartOfWeek(startDate);
// Get the end of the week containing the last day of the month, not the
// week containing the first day of the next month.
endDate.day--;
endDate = weekInfoService.getEndOfWeek(endDate);
endDate.day++; // Add a day to include items from the last day.
// Get and display the items.
let items = await getItems(startDate, endDate, filter, notDueTasks);
let defaultTimezone = cal.dtz.defaultTimezone;
for (let item of items) {
let itemStartDate = item[cal.dtz.startDateProp(item)] || item[cal.dtz.endDateProp(item)];
...
...
@@ -331,66 +379,33 @@ let monthGridView = {
let boxDate = itemStartDate.clone();
boxDate.isDate = true;
for (boxDate; boxDate.compare(itemEndDate) < (itemEndDate.isDate ? 0 : 1); boxDate.day++) {
// Ignore items outside of the range, i.e tasks without start date
// where the end date is somewhere else.
if (start && end && boxDate && (boxDate.compare(start) < 0 || boxDate.compare(end) >= 0)) {
continue;
}
for (let dayBox of this.dayTable[boxDate.icalString]) {
addItemToDaybox(document, item, boxDate, dayBox.querySelector(".items"));
let boxDateString = boxDate.icalString;
if (boxDateString in this.dayTable) {
for (let dayBox of this.dayTable[boxDateString]) {
addItemToDaybox(document, item, boxDate, dayBox.querySelector(".items"));
}
}
}
}
},
normalizeStartDate(start) {
// Make sure the start date is really a date.
let startDate = start.clone();
startDate.isDate = true;
// Find out if the start date is also shown in the first week of the
// following month. This means we can spare a month printout.
let firstDayOfNextMonth = startDate.clone();
firstDayOfNextMonth.day = 1;
firstDayOfNextMonth.month++;
if (
cal
.getWeekInfoService()
.getStartOfWeek(firstDayOfNextMonth)
.compare(startDate) <= 0
) {
startDate = firstDayOfNextMonth;
// Set the page title.
let months = container.querySelectorAll("table");
if (months.length == 1) {
document.title = months[0].querySelector(".month-title").textContent;
} else {
startDate = startDate.startOfMonth;
}
return startDate;
},
normalizeEndDate(end) {
// Copy end date, which is exclusive. For our calculations, we will
// only be handling dates and the formatToHtml() code is much cleaner with
// the range being inclusive.
let endDate = end.clone();
endDate.isDate = true;
// Find out if the end date is also shown in the last week of the
// previous month. This also means we can spare a month printout.
let lastDayOfPreviousMonth = endDate.clone();
lastDayOfPreviousMonth.month--;
lastDayOfPreviousMonth = lastDayOfPreviousMonth.endOfMonth;
if (
cal
.getWeekInfoService()
.getEndOfWeek(lastDayOfPreviousMonth)
.compare(endDate) >= 0
) {
endDate = lastDayOfPreviousMonth;
document.title =
months[0].querySelector(".month-title").textContent +
" – " +
months[months.length - 1].querySelector(".month-title").textContent;
}
return endDate;
},
/**
* Create one month from the template.
*
* @param {HTMLDocument} document
* @param {calIDateTime} startOfMonth - the first day of the month
*/
drawMonth(document, startOfMonth) {
let monthTemplate = document.getElementById("month-template");
let month = monthTemplate.content.firstElementChild.cloneNode(true);
...
...
@@ -410,7 +425,6 @@ let monthGridView = {
}
// Set up each week
let weekInfoService = cal.getWeekInfoService();
let endOfMonthView = weekInfoService.getEndOfWeek(startOfMonth.endOfMonth);
let startOfMonthView = weekInfoService.getStartOfWeek(startOfMonth);
let mainMonth = startOfMonth.month;
...
...
@@ -426,6 +440,14 @@ let monthGridView = {
return month;
},
/**
* Create one week from the template.
*
* @param {HTMLDocument} document
* @param {calIDateTime} startOfWeek - the first day of the week
* @param {number} mainMonth - the month that this week is being added to
* (for marking days that are in adjacent months)
*/
drawWeek(document, startOfWeek, mainMonth) {
const weekdayMap = [
"d0sundaysoff",
...
...
@@ -468,26 +490,32 @@ let monthGridView = {
},
};
/**
* A layout with seven days per page. The week layout is NOT aware of the
* start-of-week preferences. It always begins on a Monday.
*/
let weekPlannerView = {
dayTable: {},
async draw(document, start, end, items) {
/**
* Create the week planner view.
*
* @param {HTMLDocument} document
* @param {calIDateTime} startDate - the Monday of the first week to be displayed
* @param {calIDateTime} endDate - the Monday AFTER the last week to be displayed
* @param {integer} filter - calICalendar ITEM_FILTER flags
* @param {boolean} notDueTasks - if true, include tasks with no due date
*/
async draw(document, startDate, endDate, filter, notDueTasks) {
let container = document.getElementById("week-container");
// Table that maps YYYY-MM-DD to the DOM node container where items are to be added
let weekInfoService = cal.getWeekInfoService();
// Make sure to create tables from start to end, if passed
if (start && end) {
for (
let current = weekInfoService.getStartOfWeek(start);
current.compare(end) < 0;
current.day += 7
) {
container.appendChild(this.drawWeek(document, current));
}
// Draw the week grid(s).
for (let current = startDate.clone(); current.compare(endDate) < 0; current.day += 7) {
container.appendChild(this.drawWeek(document, current));
}
// Get and display the items.
let items = await getItems(startDate, endDate, filter, notDueTasks);
let defaultTimezone = cal.dtz.defaultTimezone;
for (let item of items) {
let itemStartDate = item[cal.dtz.startDateProp(item)] || item[cal.dtz.endDateProp(item)];
...
...
@@ -503,18 +531,32 @@ let weekPlannerView = {
let boxDate = itemStartDate.clone();
boxDate.isDate = true;
for (boxDate; boxDate.compare(itemEndDate) < (itemEndDate.isDate ? 0 : 1); boxDate.day++) {
// Ignore items outside of the range, i.e tasks without start date
// where the end date is somewhere else.
if (start && end && boxDate && (boxDate.compare(start) < 0 || boxDate.compare(end) >= 0)) {
continue;
let boxDateString = boxDate.icalString;
if (boxDateString in this.dayTable) {
addItemToDaybox(document, item, boxDate, this.dayTable[boxDateString]);
}
addItemToDaybox(document, item, boxDate, this.dayTable[boxDate.icalString]);
}
}
// Set the page title.
let weeks = container.querySelectorAll("table");
if (weeks.length == 1) {
document.title = cal.l10n.getCalString("singleLongCalendarWeek", [weeks[0].number]);
} else {
document.title = cal.l10n.getCalString("severalLongCalendarWeeks", [
weeks[0].number,
weeks[weeks.length - 1].number,
]);
}
},
drawWeek(document, startOfWeek) {
/**
* Create one week from the template.
*
* @param {HTMLDocument} document
* @param {calIDateTime} monday - the Monday of the week
*/
drawWeek(document, monday) {
// In the order they appear on the page.
const weekdayMap = [
"d1mondaysoff",
...
...
@@ -529,24 +571,19 @@ let weekPlannerView = {
let weekTemplate = document.getElementById("week-template");
let week = weekTemplate.content.firstElementChild.cloneNode(true);
week.item = startOfWeek.clone();
// Set up the week number title
let weekInfo = cal.getWeekInfoService(
);
let weekno = weekInfo.getWeekTitle(startOfWeek);
let
week
Title = cal.l10n.getCalString("WeekTitle", [weekno]);
week.rows[0].cells[0].firstElementChild.textContent = weekTitle
;
week.number = weekInfoService.getWeekTitle(monday
);
week.querySelector(".week-title").textContent = cal.l10n.getCalString("WeekTitle", [
week
.number,
])
;
// Set up the day boxes
let defaultTimezone = cal.dtz.defaultTimezone;
let currentDate = startOfWeek.clone();
let currentDate = monday.clone();
for (let i = 0; i < 7; i++) {
let day = week.rows[1].cells[i];
let titleNode = day.querySelector(".day-title");
titleNode.textContent = cal.dtz.formatter.formatDateLong(
currentDate.getInTimezone(defaultTimezone)
);
titleNode.textContent = cal.dtz.formatter.formatDateLong(currentDate);
this.dayTable[currentDate.icalString] = day.querySelector(".items");
...
...
comm/calendar/base/src/CalCalendarManager.jsm
View file @
a783ae47
...
...
@@ -905,7 +905,10 @@ function deletePrefBranch(id) {
*/
function maybeRefreshCalendar(calendar) {
if (!calendar.getProperty("disabled") && calendar.canRefresh) {
calendar.refresh();
let refreshInterval = calendar.getProperty("refreshInterval");
if (refreshInterval != "0") {
calendar.refresh();
}
}
}
...
...
comm/calendar/locales/en-US/chrome/calendar/timezones.properties
View file @
a783ae47
...
...
@@ -481,3 +481,6 @@ pref.timezone.Asia.Qostanay=Asia/Qostanay
#added with 2.2020a
pref.timezone.America.Nuuk
=
America/Nuuk
#added with 2.2021c
pref.timezone.Pacific.Kanton
=
Pacific/Kanton
comm/calendar/providers/caldav/CalDavCalendar.jsm
View file @
a783ae47
...
...
@@ -35,7 +35,7 @@ function CalDavCalendar() {
this.unmappedProperties = [];
this.mUriParams = null;
this.mItemInfoCache = {};
this.mDisabled = false;
this.mDisabled
ByDavError
= false;
this.mCalHomeSet = null;
this.mInboxUrl = null;
this.mOutboxUrl = null;
...
...
@@ -360,7 +360,7 @@ CalDavCalendar.prototype = {
return "caldav";
},
mDisabled: true,
mDisabled
ByDavError
: true,
mCalendarUserAddress: null,
get calendarUserAddress() {
...
...
@@ -1283,7 +1283,7 @@ CalDavCalendar.prototype = {
cal.LOG(`CalDAV: Disabling calendar ${this.name} due to 404`);
notifyListener(Cr.NS_ERROR_FAILURE);
return;
} else if (response.ok && this.mDisabled) {
} else if (response.ok && this.mDisabled
ByDavError
) {
// Looks like the calendar is there again, check its resource
// type first.
this.checkDavResourceType(aChangeLogListener);
...
...
@@ -1354,7 +1354,7 @@ CalDavCalendar.prototype = {
* calendars.
*/
getUpdatedItems(aUri, aChangeLogListener) {
if (this.mDisabled) {
if (this.mDisabled
ByDavError
) {
// check if maybe our calendar has become available
this.checkDavResourceType(aChangeLogListener);
return;
...
...
@@ -1620,13 +1620,14 @@ CalDavCalendar.prototype = {
let resourceType = response.firstProps["D:resourcetype"] || new Set();
if (resourceType.has("C:calendar")) {
// This is a valid calendar resource
if (this.mDisabled) {
this.mDisabled = false;
this.mReadOnly = false;
if (this.mDisabledByDavError) {
this.mDisabledByDavError = false;
}
let privs = response.firstProps["D:current-user-privilege-set"];
if (privs && privs instanceof Set) {
// Don't clear this.readOnly, only set it. The user may have write
// privileges but not want to use them.
if (!this.readOnly && privs && privs instanceof Set) {
this.readOnly = ![
"D:write",
"D:write-content",
...
...
@@ -1968,8 +1969,7 @@ CalDavCalendar.prototype = {
return;
}
localizedMessage = cal.l10n.getCalString(message, [this.mUri.spec]);
this.mReadOnly = true;
this.mDisabled = true;
this.mDisabledByDavError = true;
this.notifyError(aErrNo, localizedMessage);
this.notifyError(
modificationError ? Ci.calIErrors.MODIFICATION_FAILED : Ci.calIErrors.READ_FAILED,
...
...
comm/calendar/providers/caldav/modules/CalDavRequestHandlers.jsm
View file @
a783ae47
...
...
@@ -385,7 +385,7 @@ class CalDavWebDavSyncHandler extends XMLResponseHandler {
QueryInterface = ChromeUtils.generateQI(["nsIRequestObserver", "nsIStreamListener"]);
async doWebDAVSync() {
if (this.calendar.mDisabled) {
if (this.calendar.mDisabled
ByDavError
) {
// check if maybe our calendar has become available
this.calendar.checkDavResourceType(this.changeLogListener);
return;
...
...
@@ -763,7 +763,7 @@ class CalDavMultigetSyncHandler extends XMLResponseHandler {
QueryInterface = ChromeUtils.generateQI(["nsIRequestObserver", "nsIStreamListener"]);
doMultiGet() {
if (this.calendar.mDisabled) {
if (this.calendar.mDisabled
ByDavError
) {
// check if maybe our calendar has become available
this.calendar.checkDavResourceType(this.changeLogListener);
return;
...
...
comm/calendar/providers/ics/CalICSProvider.jsm
View file @
a783ae47
...
...
@@ -289,7 +289,12 @@ class ICSDetector {
// The content type header may include a charset, so use 'string.includes'.
if (response.ok) {
let header = response.getHeader("Content-Type");
if (header.includes("text/calendar") || header.includes("application/ics")) {
if (
header.includes("text/calendar") ||
header.includes("application/ics") ||
(response.text && response.text.includes("BEGIN:VCALENDAR"))
) {
let target = response.uri;
cal.LOG(`[calICSProvider] ${target.spec} has valid content type (via ${method} request)`);
return [this.handleCalendar(target)];
...
...
comm/calendar/providers/storage/CalStorageCalendar.jsm
View file @
a783ae47
...
...
@@ -2249,7 +2249,7 @@ CalStorageCalendar.prototype = {
// put Google's HTML description in the right place
//
fixGoogleCalendarDescriptionIfNeeded(item) {
if (item.id.endsWith("@google.com")) {
if (item.id
&& item.id
.endsWith("@google.com")) {
let description = item.getProperty("DESCRIPTION");
if (description) {
let altrep = item.getPropertyParameter("DESCRIPTION", "ALTREP");
...
...
comm/calendar/test/unit/data/previous.json
View file @
a783ae47
{
"version"
:
"2.202
0d
"
,
"version"
:
"2.202
1a
"
,
"aliases"
:
[
"AUS Central Standard Time"
,
"AUS Eastern Standard Time"
,
...
...
@@ -29,6 +29,7 @@
"Atlantic/Faeroe"
,
"Atlantic/Jan_Mayen"
,
"Aus Central W. Standard Time"
,
"Australia/Currie"
,
"Azerbaijan Standard Time"
,
"Azores Standard Time"
,
"Bahia Standard Time"
,
...
...
@@ -482,7 +483,6 @@
"Australia/Adelaide"
,
"Australia/Brisbane"
,
"Australia/Broken_Hill"
,
"Australia/Currie"
,
"Australia/Darwin"
,
"Australia/Eucla"
,
"Australia/Hobart"
,
...
...
comm/calendar/timezones/zones.json
View file @
a783ae47
{
"version"
:
"2.2021
a
"
,
"version"
:
"2.2021
c
"
,
"aliases"
:
{
"AUS Central Standard Time"
:
{
"aliasTo"
:
"Australia/Darwin"
...
...
@@ -346,6 +346,9 @@
"Pacific Standard Time (Mexico)"
:
{
"aliasTo"
:
"America/Santa_Isabel"
},
"Pacific/Enderbury"
:
{
"aliasTo"
:
"Pacific/Kanton"
},
"Pacific/Johnston"
:
{
"aliasTo"
:
"Pacific/Honolulu"
},
...
...
@@ -2107,8 +2110,9 @@
},
"Asia/Amman"
:
{
"ics"
:
[
"BEGIN:DAYLIGHT
\r\n
TZOFFSETFROM:+0200
\r\n
TZOFFSETTO:+0300
\r\n
TZNAME:EEST
\r\n
DTSTART:19700326T235959
\r\n
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1TH
\r\n
END:DAYLIGHT"
,
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+0300
\r\n
TZOFFSETTO:+0200
\r\n
TZNAME:EET
\r\n
DTSTART:19701030T010000
\r\n
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR
\r\n
END:STANDARD"
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+0300
\r\n
TZOFFSETTO:+0200
\r\n
TZNAME:EET
\r\n
DTSTART:19701030T010000
\r\n
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1FR
\r\n
END:STANDARD"
,
"BEGIN:DAYLIGHT
\r\n
TZOFFSETFROM:+0300
\r\n
TZOFFSETTO:+0300
\r\n
TZNAME:EEST
\r\n
DTSTART:20220224T235959
\r\n
RRULE:FREQ=YEARLY;BYMONTH=2;BYDAY=-1TH
\r\n
END:DAYLIGHT"
,
"BEGIN:DAYLIGHT
\r\n
TZOFFSETFROM:+0200
\r\n
TZOFFSETTO:+0300
\r\n
TZNAME:EEST
\r\n
DTSTART:20180329T235959
\r\n
RDATE:20180329T235959
\r\n
RDATE:20190328T235959
\r\n
RDATE:20200326T235959
\r\n
RDATE:20210325T235959
\r\n
END:DAYLIGHT"
],
"latitude"
:
"+0315700"
,
"longitude"
:
"+0355600"
...
...
@@ -3409,8 +3413,8 @@
},
"Pacific/Apia"
:
{
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1400
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:
1970
040
5
T040000
\r\n
R
RULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
\r\n
END:STANDARD"
,
"BEGIN:DAYLIGHT
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1400
\r\n
TZNAME:+14
\r\n
DTSTART:19700
927
T0
3
0000
\r\n
R
RULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1SU
\r\n
END:DAYLIGHT"
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1400
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:
2018
040
1
T040000
\r\n
R
DATE:20180401T040000
\r\n
RDATE:20190407T040000
\r\n
RDATE:20200405T040000
\r\n
RDATE:20210404T040000
\r\n
END:STANDARD"
,
"BEGIN:DAYLIGHT
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1400
\r\n
TZNAME:+14
\r\n
DTSTART:19700
101T000000
\r\n
RDATE:19700101
T0
0
0000
\r\n
R
DATE:20180930T030000
\r\n
RDATE:20190929T030000
\r\n
RDATE:20200927T030000
\r\n
END:DAYLIGHT"
],
"latitude"
:
"-0135000"
,
"longitude"
:
"-1714400"
...
...
@@ -3462,13 +3466,6 @@
"latitude"
:
"-0174000"
,
"longitude"
:
"+1682500"
},
"Pacific/Enderbury"
:
{
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:19700101T000000
\r\n
END:STANDARD"
],
"latitude"
:
"-0030800"
,
"longitude"
:
"-1710500"
},
"Pacific/Fakaofo"
:
{
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:19700101T000000
\r\n
END:STANDARD"
...
...
@@ -3527,6 +3524,13 @@
"latitude"
:
"+0211825"
,
"longitude"
:
"-1575130"
},
"Pacific/Kanton"
:
{
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:19700101T000000
\r\n
END:STANDARD"
],
"latitude"
:
"-0024700"
,
"longitude"
:
"-1714300"
},
"Pacific/Kiritimati"
:
{
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1400
\r\n
TZOFFSETTO:+1400
\r\n
TZNAME:+14
\r\n
DTSTART:19700101T000000
\r\n
END:STANDARD"
...
...
@@ -3667,8 +3671,8 @@
"ics"
:
[
"BEGIN:STANDARD
\r\n
TZOFFSETFROM:+1300
\r\n
TZOFFSETTO:+1300
\r\n
TZNAME:+13
\r\n
DTSTART:19700101T000000
\r\n
END:STANDARD"
],