Skip to content

fs: add Temporal.Instant support to Stats and BigIntStats#60789

Open
LiviaMedeiros wants to merge 3 commits into
nodejs:mainfrom
LiviaMedeiros:fs-stats-temporal
Open

fs: add Temporal.Instant support to Stats and BigIntStats#60789
LiviaMedeiros wants to merge 3 commits into
nodejs:mainfrom
LiviaMedeiros:fs-stats-temporal

Conversation

@LiviaMedeiros
Copy link
Copy Markdown
Member

Refs: #57891

This is a very rough draft, and probably shouldn't land until Temporal implementation is finalized and/or enabled by default.
Opening early to see if there are any objections, suggestions to naming (the *Instant properties are facing userspace and having consistent convention would be nice), or to implementation.

@LiviaMedeiros LiviaMedeiros added fs Issues and PRs related to the fs subsystem / file system. experimental Issues and PRs related to experimental features. labels Nov 20, 2025
@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Nov 20, 2025
@Renegade334
Copy link
Copy Markdown
Member

Renegade334 commented Nov 20, 2025

Since Date.prototype.toInstant() comes along with Temporal, these are fairly trivial to obtain anyway? (Although come to think of it, this would lose nanosecond precision.)

It might be better to have this as a switchable option similar to bigint, rather than adding the overhead of building a load of Temporal objects for every stats call?

@LiviaMedeiros
Copy link
Copy Markdown
Member Author

Since Date.prototype.toInstant() comes along with Temporal, these are fairly trivial to obtain anyway?

Converting from Date would have performance overhead on top of precision loss.

It might be better to have this as a switchable option similar to bigint, rather than adding the overhead of building a load of Temporal objects for every stats call?

These properties are lazy-loaded, so the overhead when not used should be minimal.

Comment thread lib/internal/fs/utils.js Outdated
Comment on lines +440 to +441
// TODO(LiviaMedeiros): TemporalInstant primordial
return new Temporal.Instant(BigInt(MathFloor(msec / kMsPerSec)) * kNsPerSecBigInt + BigInt(nsec));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're probably going to want to support building node without Temporal support for a while

Suggested change
// TODO(LiviaMedeiros): TemporalInstant primordial
return new Temporal.Instant(BigInt(MathFloor(msec / kMsPerSec)) * kNsPerSecBigInt + BigInt(nsec));
if (Temporal == null) throw 'informative error';
// TODO(LiviaMedeiros): TemporalInstant primordial
return new Temporal.Instant(BigInt(MathFloor(msec / kMsPerSec)) * kNsPerSecBigInt + BigInt(nsec));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, especially with mandatory Rust requirements.
Added the error, the message text is subject to changes (if this may land before enabling Temporal by default, it should also suggest --harmony-temporal flag)

Comment thread lib/internal/fs/utils.js
return this.atimeInstant = instantFromTimeSpecMs(this.atimeMs, this[kPartialAtimeNs]);
},
set(value) {
ObjectDefineProperty(this, 'atimeInstant', { __proto__: null, value, writable: true });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ObjectDefineProperty(this, 'atimeInstant', { __proto__: null, value, writable: true });
setOwnProperty(this, 'atimeInstant', value);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT this will make the property enumerable, even though the initial getter is not? I don't mind it, but this better be aligned with how Date setters behave.

Copy link
Copy Markdown
Contributor

@aduh95 aduh95 Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add an additional optional enumerable argument to setOwnProperty

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original getter is enumerable though

@LiviaMedeiros LiviaMedeiros marked this pull request as ready for review May 14, 2026 20:07
Comment thread doc/api/fs.md Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

❌ Patch coverage is 84.67153% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.04%. Comparing base (c24e552) to head (b4c96e5).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/fs/utils.js 84.44% 21 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #60789      +/-   ##
==========================================
- Coverage   90.05%   90.04%   -0.01%     
==========================================
  Files         714      714              
  Lines      225247   225375     +128     
  Branches    42578    42582       +4     
==========================================
+ Hits       202842   202949     +107     
- Misses      14181    14202      +21     
  Partials     8224     8224              
Files with missing lines Coverage Δ
lib/internal/errors.js 97.65% <100.00%> (+<0.01%) ⬆️
lib/internal/fs/utils.js 97.78% <84.44%> (-1.91%) ⬇️

... and 24 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread doc/api/fs.md Outdated
Comment thread lib/internal/fs/utils.js Outdated
enumerable: true,
configurable: true,
get() {
return this.atimeInstant = instantFromTimeSpecMs(this.atimeMs, this[kPartialAtimeNs]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's avoid the additional setter call

Suggested change
return this.atimeInstant = instantFromTimeSpecMs(this.atimeMs, this[kPartialAtimeNs]);
const value = instantFromTimeSpecMs(this.atimeMs, this[kPartialAtimeNs]);
setOwnProperty(this, 'atimeInstant', value);
return value;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I guess we can do the same in lazyDateFields getters.

Signed-off-by: LiviaMedeiros <livia@cirno.name>
LiviaMedeiros and others added 2 commits May 15, 2026 16:12
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

experimental Issues and PRs related to experimental features. fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants