fs.Stat fails on pre-epoch mtime (<1970-01-01T00:00:00Z)
- 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.