From 7f80f9fb8f6d9d363c6b20929c6899d592bf734d Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Fri, 9 Oct 2026 19:48:12 -0700 Subject: [PATCH] fs: preserve negative utimes timestamps `toUnixTimestamp()` silently replaced negative numeric timestamps with the current time, while negative strings and Dates were passed through as pre-epoch times. On Windows, stat times were additionally reinterpreted as unsigned so that pre-epoch times read back as post-2038 times. Treat negative times as pre-epoch on all platforms, consistent with POSIX, at the cost of post-2038 times on Windows which libuv is unable to represent. Fixes: https://github.com/nodejs/node/issues/64597 Refs: https://github.com/nodejs/node/pull/64627 Assisted-by: OpenCode Signed-off-by: Guy Bedford --- doc/api/fs.md | 9 ++++-- lib/internal/fs/utils.js | 4 --- src/node_file-inl.h | 10 ------- test/parallel/test-fs-utimes-y2K38.js | 43 +++++++++++---------------- test/parallel/test-fs-utimes.js | 40 +++++++++++-------------- 5 files changed, 43 insertions(+), 63 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index d6eb4208ef0a..b8b2b9363875 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -2229,7 +2229,8 @@ Change the file system timestamps of the object referenced by `path`. The `atime` and `mtime` arguments follow these rules: * Values can be either numbers representing Unix epoch time, `Date`s, or a - numeric string like `'123456789.0'`. + numeric string like `'123456789.0'`. Negative values represent times before + the Unix epoch. * If the value can not be converted to a number, or is `NaN`, `Infinity`, or `-Infinity`, an `Error` will be thrown. @@ -5316,7 +5317,8 @@ Change the file system timestamps of the object referenced by `path`. The `atime` and `mtime` arguments follow these rules: * Values can be either numbers representing Unix epoch time in seconds, - `Date`s, or a numeric string like `'123456789.0'`. + `Date`s, or a numeric string like `'123456789.0'`. Negative values represent + times before the Unix epoch. * If the value can not be converted to a number, or is `NaN`, `Infinity`, or `-Infinity`, an `Error` will be thrown. @@ -8250,6 +8252,9 @@ The times in the stat object have the following semantics: Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As of 0.12, `ctime` is not "creation time", and on Unix systems, it never was. +On Windows, times are limited to the range of a signed 32-bit number of seconds +from the Unix epoch, so times after `2038-01-19T03:14:07Z` are not supported. + ### Class: `fs.StatFs`