diff --git a/src/scripting_api/util.js b/src/scripting_api/util.js index cd2f2a6b4502b..66f014c50fd9e 100644 --- a/src/scripting_api/util.js +++ b/src/scripting_api/util.js @@ -349,53 +349,53 @@ class Util extends PDFObject { this.#dateActionsCache.set(cFormat, actions); cFormat.replaceAll( /(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g, - function (match, d, m, y, H, M, s) { + function (_match, d, m, y, H, M, s) { if (d) { - actions.push((n, date) => { + actions.push((n, data) => { if (n >= 1 && n <= 31) { - date.setDate(n); + data.day = n; return true; } return false; }); } else if (m) { - actions.push((n, date) => { + actions.push((n, data) => { if (n >= 1 && n <= 12) { - date.setMonth(n - 1); + data.month = n - 1; return true; } return false; }); } else if (y) { - actions.push((n, date) => { + actions.push((n, data) => { if (n < 50) { n += 2000; } else if (n < 100) { n += 1900; } - date.setYear(n); + data.year = n; return true; }); } else if (H) { - actions.push((n, date) => { + actions.push((n, data) => { if (n >= 0 && n <= 23) { - date.setHours(n); + data.hours = n; return true; } return false; }); } else if (M) { - actions.push((n, date) => { + actions.push((n, data) => { if (n >= 0 && n <= 59) { - date.setMinutes(n); + data.minutes = n; return true; } return false; }); } else if (s) { - actions.push((n, date) => { + actions.push((n, data) => { if (n >= 0 && n <= 59) { - date.setSeconds(n); + data.seconds = n; return true; } return false; @@ -409,10 +409,17 @@ class Util extends PDFObject { const number = /\d+/g; let i = 0; let array; - const date = new Date(0); + const data = { + year: new Date().getFullYear(), + month: 0, + day: 1, + hours: 12, + minutes: 0, + seconds: 0, + }; while ((array = number.exec(cDate)) !== null) { if (i < actions.length) { - if (!actions[i++](parseInt(array[0]), date)) { + if (!actions[i++](parseInt(array[0]), data)) { return null; } } else { @@ -424,7 +431,14 @@ class Util extends PDFObject { return null; } - return date; + return new Date( + data.year, + data.month, + data.day, + data.hours, + data.minutes, + data.seconds + ); } scand(cFormat, cDate) { @@ -605,10 +619,10 @@ class Util extends PDFObject { } const data = { - year: 2000, + year: new Date().getFullYear(), month: 0, day: 1, - hours: 0, + hours: 12, minutes: 0, seconds: 0, am: null, diff --git a/test/integration/scripting_spec.mjs b/test/integration/scripting_spec.mjs index 1228e4ff13edf..0a157479b0904 100644 --- a/test/integration/scripting_spec.mjs +++ b/test/integration/scripting_spec.mjs @@ -2522,4 +2522,42 @@ describe("Interaction", () => { ); }); }); + + describe("Date creation must be timezone consistent", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("bug1934157.pdf", "[data-annotation-id='24R']"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must check that date entered by the user is consistent", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + if (browserName === "firefox") { + // Skip the test for Firefox as it doesn't support the timezone + // feature yet with BiDi. + // See https://github.com/puppeteer/puppeteer/issues/13344. + // TODO: Remove this check once the issue is fixed. + return; + } + + await waitForScripting(page); + + await page.emulateTimezone("Pacific/Honolulu"); + + const expectedDate = "02/01/2000"; + await page.type(getSelector("24R"), expectedDate); + await page.click(getSelector("25R")); + await waitForSandboxTrip(page); + + const date = await page.$eval(getSelector("24R"), el => el.value); + expect(date).withContext(`In ${browserName}`).toEqual(expectedDate); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 89657327d46e4..9419dafdc5390 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -683,3 +683,4 @@ !issue18956.pdf !issue19083.pdf !issue19120.pdf +!bug1934157.pdf diff --git a/test/pdfs/bug1934157.pdf b/test/pdfs/bug1934157.pdf new file mode 100755 index 0000000000000..f0feacbccbff2 Binary files /dev/null and b/test/pdfs/bug1934157.pdf differ diff --git a/test/unit/scripting_spec.js b/test/unit/scripting_spec.js index 94ed4aa7f8118..9ce2699d48106 100644 --- a/test/unit/scripting_spec.js +++ b/test/unit/scripting_spec.js @@ -245,10 +245,10 @@ describe("Scripting", function () { expect(new Date(value)).toEqual(date); value = await myeval(`util.scand("mmddyyyy", "07/15/2007").toString()`); - expect(new Date(value)).toEqual(new Date("07/15/2007")); + expect(new Date(value)).toEqual(new Date("07/15/2007 12:00:00")); value = await myeval(`util.scand("mmddyyyy", "07a15b2007").toString()`); - expect(new Date(value)).toEqual(new Date("07/15/2007")); + expect(new Date(value)).toEqual(new Date("07/15/2007 12:00:00")); }); }); @@ -630,8 +630,9 @@ describe("Scripting", function () { ); }; - await check("05", "dd", "2000/01/05"); - await check("12", "mm", "2000/12/01"); + const year = new Date().getFullYear(); + await check("05", "dd", `${year}/01/05`); + await check("12", "mm", `${year}/12/01`); await check("2022", "yyyy", "2022/01/01"); await check("a1$9bbbb21", "dd/mm/yyyy", "2021/09/01"); await check("1/2/2024", "dd/mm/yyyy", "2024/02/01");