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
12a433a7
Commit
12a433a7
authored
Oct 23, 2021
by
Carsten Schoenert
Browse files
New upstream version 91.2.1
parent
3c888442
Changes
641
Hide whitespace changes
Inline
Side-by-side
comm/calendar/base/content/imip-bar.js
View file @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
...
...
@@ -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 @
12a433a7
{
"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 @
12a433a7
{
"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"
],