Skip to content

fs.Stat fails on pre-epoch mtime (<1970-01-01T00:00:00Z) #32369

@daneroo

Description

@daneroo
  • Version: v13.10.1
  • Platform: Darwin dirac.imetrical.com 18.7.0 Darwin Kernel Version 18.7.0: Sun Dec 1 18:59:03 PST 2019; root:xnu-4903.278.19~1/RELEASE_X86_64 x86_64
  • Subsystem: fs.stat

What steps will reproduce the bug?

// statPreEpoch.js
const fs = require('fs')
const path = 'coco.txt'
const { mtime } = fs.statSync(path)
console.log(`mtime of ${path}: ${mtime}`)

This is on Darwin (macOS)

# This is correct
$ touch -mt 197001010000.00 coco.txt
$ stat coco.txt 
16777220 104232499 -rw-r--r-- 1 daniel staff 0 0 "Mar 19 13:26:22 2020" "Jan  1 00:00:00 1970" "Mar 19 15:01:21 2020" "Dec 31 19:00:00 1969" 4096 0 0 coco.txt
$ node statPreEpoch.js 
mtime of coco.txt: Thu Jan 01 1970 00:00:00 GMT-0500 (GMT-05:00)

# This is the bug:
touch -mt 196805160000.00 coco.txt 
stat coco.txt 
16777220 104232499 -rw-r--r-- 1 daniel staff 0 0 "Mar 19 13:26:22 2020" "May 16 00:00:00 1968" "Mar 19 15:00:23 2020" "Dec 31 19:00:00 1969" 4096 0 0 coco.txt
$ node statPreEpoch.js 
mtime of coco.txt: Invalid Date

This is on Linux (in Docker

$ docker run --rm -it -v $(pwd)/statPreEpoch.js:/src/statPreEpoch.js node:13.10 bash
$ uname -a
Linux 38f95bbffb38 4.19.76-linuxkit #1 SMP Thu Oct 17 19:31:58 UTC 2019 x86_64 GNU/Linux
$ touch -mt 197001010000.00 coco.txt
$ stat coco.txt 
  File: coco.txt
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: abh/171d	Inode: 2910905     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-03-19 19:10:48.080137057 +0000
Modify: 1970-01-01 00:00:00.000000000 +0000
Change: 2020-03-19 19:10:48.080137057 +0000
$ node  /src/statPreEpoch.js
mtime of coco.txt: Thu Jan 01 1970 00:00:00 GMT+0000 (Coordinated Universal Time)

# This is the bug
$ touch -mt 196805160000.00 coco.txt 
$ stat coco.txt 
  File: coco.txt
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: abh/171d	Inode: 2910905     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-03-19 19:10:48.080137057 +0000
Modify: 1968-05-16 00:00:00.000000000 +0000
Change: 2020-03-19 19:12:24.343012135 +0000
 Birth: -
$ node  /src/statPreEpoch.js
mtime of coco.txt: Invalid Date

How often does it reproduce? Is there a required condition?

Every time that mtime < unix epoch (1970-01-01T00:00:00Z)

What is the expected behavior?

Return a valid Date Object, for example

$ node  /src/statPreEpoch.js
mtime of coco.txt: Thu May 16 1968 00:00:00 GMT+0000 (Coordinated Universal Time)
> new Date("1968-05-16T00:00:00-04:00")
1968-05-16T04:00:00.000Z
> new Date("1968-05-16T00:00:00-04:00").getTime()
-51393600000

What do you see instead?

$ node  /src/statPreEpoch.js
mtime of coco.txt: Invalid Date

Additional information

I discovered this behavior by trying to use fs.utimes which is also not able to correctly handle dates before unix epoch, although fs.utimes seems to have a workaround by using the string representation of unix time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.fsIssues and PRs related to the fs subsystem / file system.libuvIssues and PRs related to the libuv dependency or the uv binding.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions