summaryrefslogtreecommitdiffstats
path: root/comm/calendar/base/src/CalWeekInfoService.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'comm/calendar/base/src/CalWeekInfoService.jsm')
-rw-r--r--comm/calendar/base/src/CalWeekInfoService.jsm113
1 files changed, 113 insertions, 0 deletions
diff --git a/comm/calendar/base/src/CalWeekInfoService.jsm b/comm/calendar/base/src/CalWeekInfoService.jsm
new file mode 100644
index 0000000000..a94145f44e
--- /dev/null
+++ b/comm/calendar/base/src/CalWeekInfoService.jsm
@@ -0,0 +1,113 @@
+/* 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/. */
+
+var EXPORTED_SYMBOLS = ["CalWeekInfoService"];
+
+var { XPCOMUtils } = ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
+
+const SUNDAY = 0;
+const THURSDAY = 4;
+
+const lazy = {};
+
+XPCOMUtils.defineLazyPreferenceGetter(lazy, "startWeekday", "calendar.week.start", SUNDAY);
+
+function CalWeekInfoService() {
+ this.wrappedJSObject = this;
+}
+CalWeekInfoService.prototype = {
+ QueryInterface: ChromeUtils.generateQI(["calIWeekInfoService"]),
+ classID: Components.ID("{6877bbdd-f336-46f5-98ce-fe86d0285cc1}"),
+
+ // calIWeekInfoService:
+ getWeekTitle(aDateTime) {
+ /**
+ * This implementation is based on the ISO 8601 standard.
+ * ISO 8601 defines week one as the first week with at least 4
+ * days, and defines Monday as the first day of the week.
+ * Equivalently, the week one is the week with the first Thursday.
+ *
+ * This implementation uses the second definition, because it
+ * enables the user to set a different start-day of the week
+ * (Sunday instead of Monday is a common setting). If the first
+ * definition was used, all week-numbers could be off by one
+ * depending on the week start day. (For example, if weeks start
+ * on Sunday, a year that starts on Thursday has only 3 days
+ * [Thu-Sat] in that week, so it would be part of the last week of
+ * the previous year, but if weeks start on Monday, the year would
+ * have four days [Thu-Sun] in that week, so it would be counted
+ * as week 1.)
+ */
+
+ // The week number is the number of days since the start of week 1,
+ // divided by 7 and rounded up. Week 1 is the week containing the first
+ // Thursday of the year.
+ // Thus, the week number of any day is the same as the number of days
+ // between the Thursday of that week and the Thursday of week 1, divided
+ // by 7 and rounded up. (This takes care of days at end/start of a year
+ // which may be part of first/last week in the other year.)
+ // The Thursday of a week is the Thursday that follows the first day
+ // of the week.
+ // The week number of a day is the same as the week number of the first
+ // day of the week. (This takes care of days near the start of the year,
+ // which may be part of the week counted in the previous year.) So we
+ // need the startWeekday.
+
+ // The number of days since the start of the week.
+ // Notice that the result of the subtraction might be negative.
+ // We correct for that by adding 7, and then using the remainder operator.
+ let sinceStartOfWeek = (aDateTime.weekday - lazy.startWeekday + 7) % 7;
+
+ // The number of days to Thursday is the difference between Thursday
+ // and the start-day of the week (again corrected for negative values).
+ let startToThursday = (THURSDAY - lazy.startWeekday + 7) % 7;
+
+ // The yearday number of the Thursday this week.
+ let thisWeeksThursday = aDateTime.yearday - sinceStartOfWeek + startToThursday;
+
+ if (thisWeeksThursday < 1) {
+ // For the first few days of the year, we still are in week 52 or 53.
+ let lastYearDate = aDateTime.clone();
+ lastYearDate.year -= 1;
+ thisWeeksThursday += lastYearDate.endOfYear.yearday;
+ } else if (thisWeeksThursday > aDateTime.endOfYear.yearday) {
+ // For the last few days of the year, we already are in week 1.
+ thisWeeksThursday -= aDateTime.endOfYear.yearday;
+ }
+
+ let weekNumber = Math.ceil(thisWeeksThursday / 7);
+ return weekNumber;
+ },
+
+ /**
+ * gets the first day of a week of a passed day under consideration
+ * of the preference setting "calendar.week.start"
+ *
+ * @param aDate a date time object
+ * @returns a dateTime-object denoting the first day of the week
+ */
+ getStartOfWeek(aDate) {
+ let date = aDate.clone();
+ date.isDate = true;
+ let offset = lazy.startWeekday - aDate.weekday;
+ date.day += offset;
+ if (offset > 0) {
+ date.day -= 7;
+ }
+ return date;
+ },
+
+ /**
+ * gets the last day of a week of a passed day under consideration
+ * of the preference setting "calendar.week.start"
+ *
+ * @param aDate a date time object
+ * @returns a dateTime-object denoting the last day of the week
+ */
+ getEndOfWeek(aDate) {
+ let date = this.getStartOfWeek(aDate);
+ date.day += 6;
+ return date;
+ },
+};