mirror of
https://github.com/zadam/trilium.git
synced 2025-12-04 22:44:25 +01:00
edited notes: handle timezone differences between client and server
This commit is contained in:
parent
fda2fb9392
commit
f5ad2ca8ae
@ -1,16 +1,34 @@
|
|||||||
|
import cls from '../../services/cls.js';
|
||||||
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
||||||
import dayjs from "dayjs";
|
|
||||||
import { resolveDateParams } from "./edited-notes.js";
|
import { resolveDateParams } from "./edited-notes.js";
|
||||||
|
|
||||||
function resolveAsDate(dateStr: string) {
|
// test date setup
|
||||||
return resolveDateParams(dateStr).date;
|
// client: UTC+1
|
||||||
|
// server: UTC
|
||||||
|
// day/month/year is changed when server converts a client date to to UTC
|
||||||
|
const clientDate = "2025-01-01 00:11:11.000+0100";
|
||||||
|
const serverDate = "2024-12-31 23:11:11.000Z";
|
||||||
|
|
||||||
|
// expected values - from client's point of view
|
||||||
|
const expectedToday = "2025-01-01";
|
||||||
|
const expectedTodayMinus1 = "2024-12-31";
|
||||||
|
const expectedMonth = "2025-01";
|
||||||
|
const expectedMonthMinus2 = "2024-11";
|
||||||
|
const expectedYear = "2025";
|
||||||
|
const expectedYearMinus1 = "2024";
|
||||||
|
|
||||||
|
function runTest(dateStrToResolve: string, expectedDate: string) {
|
||||||
|
cls.init(() => {
|
||||||
|
cls.set("localNowDateTime", clientDate);
|
||||||
|
const resolvedDate = resolveDateParams(dateStrToResolve).date;
|
||||||
|
expect(resolvedDate).toBe(expectedDate);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("edited-notes::resolveAsDate", () => {
|
describe("edited-notes::resolveDateParams", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set a fixed date and time before each test
|
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
vi.setSystemTime(new Date('2012-11-10T23:22:21Z')); // NOTE!!: Date wrap in my timezone
|
vi.setSystemTime(new Date(serverDate));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -18,59 +36,40 @@ describe("edited-notes::resolveAsDate", () => {
|
|||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("resolves 'TODAY' to today's date", () => {
|
it("resolves 'TODAY' to today's date", () => {
|
||||||
const expectedDate = dayjs().format("YYYY-MM-DD");
|
runTest("TODAY", expectedToday);
|
||||||
const resolvedDate = resolveAsDate("TODAY");
|
|
||||||
expect(resolvedDate).toBe(expectedDate);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'MONTH' to current month", () => {
|
it("resolves 'MONTH' to current month", () => {
|
||||||
const expectedMonth = dayjs().format("YYYY-MM");
|
runTest("MONTH", expectedMonth);
|
||||||
const resolvedMonth = resolveAsDate("MONTH");
|
|
||||||
expect(resolvedMonth).toBe(expectedMonth);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'YEAR' to current year", () => {
|
it("resolves 'YEAR' to current year", () => {
|
||||||
const expectedYear = dayjs().format("YYYY");
|
runTest("YEAR", expectedYear);
|
||||||
const resolvedYear = resolveAsDate("YEAR");
|
|
||||||
expect(resolvedYear).toBe(expectedYear);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'TODAY-1' to yesterday's date", () => {
|
it("resolves 'TODAY-1' to yesterday's date", () => {
|
||||||
const expectedDate = dayjs().subtract(1, "day").format("YYYY-MM-DD");
|
runTest("TODAY-1", expectedTodayMinus1);
|
||||||
const resolvedDate = resolveAsDate("TODAY-1");
|
|
||||||
expect(resolvedDate).toBe(expectedDate);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'MONTH-2' to 2 months ago", () => {
|
it("resolves 'MONTH-2' to 2 months ago", () => {
|
||||||
const expectedMonth = dayjs().subtract(2, "month").format("YYYY-MM");
|
runTest("MONTH-2", expectedMonthMinus2);
|
||||||
const resolvedMonth = resolveAsDate("MONTH-2");
|
|
||||||
expect(resolvedMonth).toBe(expectedMonth);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'YEAR+1' to next year", () => {
|
it("resolves 'YEAR-1' to last year", () => {
|
||||||
const expectedYear = dayjs().add(1, "year").format("YYYY");
|
runTest("YEAR-1", expectedYearMinus1);
|
||||||
const resolvedYear = resolveAsDate("YEAR+1");
|
|
||||||
expect(resolvedYear).toBe(expectedYear);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns original string for unrecognized keyword", () => {
|
it("returns original string for unrecognized keyword", () => {
|
||||||
const unrecognizedString = "NOT_A_DYNAMIC_DATE";
|
runTest("FOO", "FOO");
|
||||||
const resolvedString = resolveAsDate(unrecognizedString);
|
|
||||||
expect(resolvedString).toBe(unrecognizedString);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns original string for partially recognized keyword", () => {
|
it("returns original string for partially recognized keyword", () => {
|
||||||
const partialString = "TODAY-";
|
runTest("TODAY-", "TODAY-");
|
||||||
const resolvedString = resolveAsDate(partialString);
|
|
||||||
expect(resolvedString).toBe(partialString);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("resolves 'today' (lowercase) to today's date", () => {
|
it("resolves 'today' (lowercase) to today's date", () => {
|
||||||
const expectedDate = dayjs().format("YYYY-MM-DD");
|
runTest("today", expectedToday);
|
||||||
const resolvedDate = resolveAsDate("today");
|
|
||||||
expect(resolvedDate).toBe(expectedDate);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
import beccaService from "../../becca/becca_service.js";
|
import beccaService from "../../becca/becca_service.js";
|
||||||
import sql from "../../services/sql.js";
|
import sql from "../../services/sql.js";
|
||||||
import cls from "../../services/cls.js";
|
import cls from "../../services/cls.js";
|
||||||
@ -6,7 +7,7 @@ import type { Request } from "express";
|
|||||||
import { NotePojo } from "../../becca/becca-interface.js";
|
import { NotePojo } from "../../becca/becca-interface.js";
|
||||||
import type BNote from "../../becca/entities/bnote.js";
|
import type BNote from "../../becca/entities/bnote.js";
|
||||||
import { EditedNotesResponse } from "@triliumnext/commons";
|
import { EditedNotesResponse } from "@triliumnext/commons";
|
||||||
import dayjs from "dayjs";
|
import dateUtils from "../../services/date_utils.js";
|
||||||
|
|
||||||
interface NotePath {
|
interface NotePath {
|
||||||
noteId: string;
|
noteId: string;
|
||||||
@ -85,7 +86,7 @@ function getNotePathData(note: BNote): NotePath | undefined {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDateFromKeywordAndDelta(keyword: string, delta: number): string {
|
function formatDateFromKeywordAndDelta(startingDate: dayjs.Dayjs, keyword: string, delta: number): string {
|
||||||
const formatMap = new Map<string, { format: string, addUnit: dayjs.UnitType }>([
|
const formatMap = new Map<string, { format: string, addUnit: dayjs.UnitType }>([
|
||||||
["today", { format: "YYYY-MM-DD", addUnit: "day" }],
|
["today", { format: "YYYY-MM-DD", addUnit: "day" }],
|
||||||
["month", { format: "YYYY-MM", addUnit: "month" }],
|
["month", { format: "YYYY-MM", addUnit: "month" }],
|
||||||
@ -98,7 +99,7 @@ function formatDateFromKeywordAndDelta(keyword: string, delta: number): string {
|
|||||||
throw new Error(`Unrecognized keyword: ${keyword}`);
|
throw new Error(`Unrecognized keyword: ${keyword}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = dayjs().add(delta, handler.addUnit);
|
const date = startingDate.add(delta, handler.addUnit);
|
||||||
return date.format(handler.format);
|
return date.format(handler.format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,8 @@ export function resolveDateParams(dateStr: string): DateFilter {
|
|||||||
const keyword = match[1].toLowerCase();
|
const keyword = match[1].toLowerCase();
|
||||||
const delta = match[2] ? parseInt(match[2]) : 0;
|
const delta = match[2] ? parseInt(match[2]) : 0;
|
||||||
|
|
||||||
const date = formatDateFromKeywordAndDelta(keyword, delta);
|
const clientDate = dayjs(dateUtils.localNowDate());
|
||||||
|
const date = formatDateFromKeywordAndDelta(clientDate, keyword, delta);
|
||||||
return {
|
return {
|
||||||
date: `${date}`
|
date: `${date}`
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user