From cafa3afec615079767ba1fd7ecff9a10ae76a5e7 Mon Sep 17 00:00:00 2001 From: Gihoon1123 Date: Mon, 20 Jul 2026 22:16:17 +0900 Subject: [PATCH 1/3] fs: preserve negative utimes timestamps Signed-off-by: Gihoon1123 --- lib/internal/fs/utils.js | 4 ---- test/parallel/test-fs-utimes.js | 9 ++++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 70aaa7e7c58e..08bc22864e8e 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -4,7 +4,6 @@ const { ArrayIsArray, BigInt, Date, - DateNow, DatePrototypeGetTime, ErrorCaptureStackTrace, FunctionPrototypeCall, @@ -786,9 +785,6 @@ function toUnixTimestamp(time, name = 'time') { return +time; } if (NumberIsFinite(time)) { - if (time < 0) { - return DateNow() / 1000; - } return time; } if (isDate(time)) { diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index fc11c0791ddb..541fe08c987b 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -46,7 +46,7 @@ function stat_resource(resource, statSync = fs.statSync) { } function check_mtime(resource, mtime, statSync) { - mtime = fs._toUnixTimestamp(mtime); + mtime = getExpectedMtime(mtime); const stats = stat_resource(resource, statSync); const real_mtime = fs._toUnixTimestamp(stats.mtime); return mtime - real_mtime; @@ -64,14 +64,17 @@ function expect_ok(syscall, resource, err, atime, mtime, statSync) { assert( // Check up to single-second precision. // Sub-second precision is OS and fs dependent. - !err && (mtime_diff < 2) || err && err.code === 'ENOSYS', + !err && (Math.abs(mtime_diff) < 2) || err && err.code === 'ENOSYS', `FAILED: expect_ok ${util.inspect(arguments)} check_mtime: ${mtime_diff}` ); } function getExpectedMtime(mtime) { - // Negative numeric timestamps are normalized to "now" at call time. + // Keep negative numeric timestamps so the test catches normalization to now. + if (typeof mtime === 'number' && mtime < 0) { + return mtime; + } return fs._toUnixTimestamp(mtime); } From 6cb392333c63a3f37b4c5e05e0af19da413fab2e Mon Sep 17 00:00:00 2001 From: Gihoon1123 Date: Tue, 29 Sep 2026 17:53:31 +0900 Subject: [PATCH 2/3] test: skip negative utimes on AIX Signed-off-by: Gihoon1123 --- test/parallel/test-fs-utimes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index 541fe08c987b..e6a8e310ee1b 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -88,7 +88,7 @@ const cases = [ [asPath, new Date()], [asPath, 123456.789], [asPath, stats.mtime], - [asPath, '123456', -1], + ...(common.isAIX ? [] : [[asPath, '123456', -1]]), [asPath, new Date('2017-04-08T17:59:38.008Z')], [asUrl, new Date()], ]; From 30fa54a3feb395eb27f42b0f70901936184ac406 Mon Sep 17 00:00:00 2001 From: GiHoon1123 Date: Wed, 30 Sep 2026 17:45:44 +0900 Subject: [PATCH 3/3] test: skip negative utimes on Windows Signed-off-by: GiHoon1123 --- test/parallel/test-fs-utimes.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-fs-utimes.js b/test/parallel/test-fs-utimes.js index e6a8e310ee1b..767626122aa8 100644 --- a/test/parallel/test-fs-utimes.js +++ b/test/parallel/test-fs-utimes.js @@ -88,7 +88,9 @@ const cases = [ [asPath, new Date()], [asPath, 123456.789], [asPath, stats.mtime], - ...(common.isAIX ? [] : [[asPath, '123456', -1]]), + // AIX rejects negative timestamps outright; Windows wraps them into a + // post-2038 date (see test-fs-utimes-y2K38.js). + ...(common.isAIX || common.isWindows ? [] : [[asPath, '123456', -1]]), [asPath, new Date('2017-04-08T17:59:38.008Z')], [asUrl, new Date()], ];