mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 15:19:01 +02:00
feat(First-day-of-the-week and date-notes)!: make any day configurable to become first day of the week and make date-notes ISO 8601-compliant
Section 4.1.4.1 ISO 8601-1 https://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf
This commit is contained in:
parent
e1a0452448
commit
89879a6851
@ -1415,8 +1415,13 @@
|
||||
"title": "Localization",
|
||||
"language": "Language",
|
||||
"first-day-of-the-week": "First day of the week",
|
||||
"sunday": "Sunday",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"first-week-of-the-year": "First week of the year",
|
||||
"first-week-contains-first-day": "First week contains first day of the year",
|
||||
"first-week-contains-first-thursday": "First week contains first Thursday of the year",
|
||||
|
@ -73,13 +73,21 @@ function DateSettings() {
|
||||
return (
|
||||
<>
|
||||
<OptionsRow name="first-day-of-week" label={t("i18n.first-day-of-the-week")}>
|
||||
<FormInlineRadioGroup
|
||||
<FormSelect
|
||||
name="first-day-of-week"
|
||||
currentValue={firstDayOfWeek}
|
||||
onChange={setFirstDayOfWeek}
|
||||
keyProperty="value"
|
||||
titleProperty="label"
|
||||
values={[
|
||||
{ value: "0", label: t("i18n.sunday") },
|
||||
{ value: "1", label: t("i18n.monday") }
|
||||
{ value: "1", label: t("i18n.monday") },
|
||||
{ value: "2", label: t("i18n.tuesday") },
|
||||
{ value: "3", label: t("i18n.wednesday") },
|
||||
{ value: "4", label: t("i18n.thursday") },
|
||||
{ value: "5", label: t("i18n.friday") },
|
||||
{ value: "6", label: t("i18n.saturday") },
|
||||
{ value: "7", label: t("i18n.sunday") },
|
||||
]}
|
||||
currentValue={firstDayOfWeek} onChange={setFirstDayOfWeek}
|
||||
/>
|
||||
</OptionsRow>
|
||||
|
||||
|
@ -16,10 +16,12 @@ import searchService from "../services/search/services/search.js";
|
||||
import sql from "./sql.js";
|
||||
import { t } from "i18next";
|
||||
import { ordinal } from "./i18n.js";
|
||||
import isoWeek from "dayjs/plugin/isoWeek.js";
|
||||
|
||||
dayjs.extend(isSameOrAfter);
|
||||
dayjs.extend(quarterOfYear);
|
||||
dayjs.extend(advancedFormat);
|
||||
dayjs.extend(isoWeek);
|
||||
|
||||
const CALENDAR_ROOT_LABEL = "calendarRoot";
|
||||
const YEAR_LABEL = "yearNote";
|
||||
@ -295,88 +297,16 @@ function getMonthNote(dateStr: string, _rootNote: BNote | null = null): BNote {
|
||||
}
|
||||
|
||||
function getWeekStartDate(date: Dayjs): Dayjs {
|
||||
const day = date.day();
|
||||
let diff: number;
|
||||
|
||||
if (optionService.getOption("firstDayOfWeek") === "0") { // Sunday
|
||||
diff = date.date() - day + (day === 0 ? -6 : 1); // adjust when day is sunday
|
||||
} else { // Monday
|
||||
diff = date.date() - day;
|
||||
}
|
||||
|
||||
const startDate = date.clone().date(diff);
|
||||
return startDate;
|
||||
const firstDayISO = parseInt(optionService.getOptionOrNull("firstDayOfWeek") ?? "1", 10);
|
||||
const day = date.isoWeekday();
|
||||
const diff = (day - firstDayISO + 7) % 7;
|
||||
return date.clone().subtract(diff, "day").startOf("day");
|
||||
}
|
||||
|
||||
// TODO: Duplicated with getWeekNumber in src/public/app/widgets/buttons/calendar.ts
|
||||
// Maybe can be merged later in monorepo setup
|
||||
function getWeekNumberStr(date: Dayjs): string {
|
||||
const year = date.year();
|
||||
const dayOfWeek = (day: number) =>
|
||||
(day - parseInt(optionService.getOption("firstDayOfWeek")) + 7) % 7;
|
||||
|
||||
// Get first day of the year and adjust to first week start
|
||||
const jan1 = date.clone().year(year).month(0).date(1);
|
||||
const jan1Weekday = jan1.day();
|
||||
const dayOffset = dayOfWeek(jan1Weekday);
|
||||
let firstWeekStart = jan1.clone().subtract(dayOffset, "day");
|
||||
|
||||
// Adjust based on week rule
|
||||
switch (parseInt(optionService.getOption("firstWeekOfYear"))) {
|
||||
case 1: { // ISO 8601: first week contains Thursday
|
||||
const thursday = firstWeekStart.clone().add(3, "day"); // Monday + 3 = Thursday
|
||||
if (thursday.year() < year) {
|
||||
firstWeekStart = firstWeekStart.add(7, "day");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: { // minDaysInFirstWeek rule
|
||||
const daysInFirstWeek = 7 - dayOffset;
|
||||
if (daysInFirstWeek < parseInt(optionService.getOption("minDaysInFirstWeek"))) {
|
||||
firstWeekStart = firstWeekStart.add(7, "day");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// default case 0: week containing Jan 1 → already handled
|
||||
}
|
||||
|
||||
const diffDays = date.startOf("day").diff(firstWeekStart.startOf("day"), "day");
|
||||
const weekNumber = Math.floor(diffDays / 7) + 1;
|
||||
|
||||
// Handle case when date is before first week start → belongs to last week of previous year
|
||||
if (weekNumber <= 0) {
|
||||
return getWeekNumberStr(date.subtract(1, "day"));
|
||||
}
|
||||
|
||||
// Handle case when date belongs to first week of next year
|
||||
const nextYear = year + 1;
|
||||
const jan1Next = date.clone().year(nextYear).month(0).date(1);
|
||||
const jan1WeekdayNext = jan1Next.day();
|
||||
const offsetNext = dayOfWeek(jan1WeekdayNext);
|
||||
let nextYearWeekStart = jan1Next.clone().subtract(offsetNext, "day");
|
||||
|
||||
switch (parseInt(optionService.getOption("firstWeekOfYear"))) {
|
||||
case 1: {
|
||||
const thursday = nextYearWeekStart.clone().add(3, "day");
|
||||
if (thursday.year() < nextYear) {
|
||||
nextYearWeekStart = nextYearWeekStart.add(7, "day");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
const daysInFirstWeek = 7 - offsetNext;
|
||||
if (daysInFirstWeek < parseInt(optionService.getOption("minDaysInFirstWeek"))) {
|
||||
nextYearWeekStart = nextYearWeekStart.add(7, "day");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (date.isSameOrAfter(nextYearWeekStart)) {
|
||||
return `${nextYear}-W01`;
|
||||
}
|
||||
|
||||
return `${year}-W${weekNumber.toString().padStart(2, "0")}`;
|
||||
const isoYear = date.isoWeekYear();
|
||||
const isoWeekNum = date.isoWeek();
|
||||
return `${isoYear}-W${isoWeekNum.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
function getWeekFirstDayNote(dateStr: string, rootNote: BNote | null = null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user