Fwiw, it's much worse for 64-bit nanoseconds, running out in the year 2262 for signed, and the year 2554 for unsigned. As for who needs nanoseconds, trading systems, particle physics, and globally distributed systems do.
Which systems use a single variable for nanoseconds time? The APIs I know of all use a struct with two members, one for seconds and the other for the nanoseconds within the second.
At least ext4 (and its predecessors ext2/ext3) uses 32-bit seconds for the timestamps, and has separate fields (available only when the inode size of the filesystem is greater than 128 bytes) for nanoseconds and for extending the seconds fields to 34 bits.
True enough [1] but the end result is actually a slightly shorter time range ("only" 544 years vs. 584 years for a "true" 64-bit ns-resolution timestamp). Though, admittedly, when we get anywhere near to the year 2514 and happen to still be using ext4 (or yet another extN+1), the format can always be extended again.
Also, I may have been wrong about XFS on Linux at least; though the data structures are not as easy to follow as for ext4, they seem to be using struct timespec64 for all times, which has both separate fields for seconds and nanoseconds as well as a 64-bit-wide seconds field [2], covering a range of 584 billion years.
MAX_SAFE_INTEGER = 2^53 - 1 = 9007199254740991. The next integer 2^53 is representable, while the following one 2^53 + 1 isn't.
2^53 + 1 milliseconds = 9007199254740993 milliseconds = 104249991 days 8 hours 59 minutes 0.993 seconds. Since the zero point is midnight 1970-01-01, we reach the first non-representable millisecond at 287396-10-12T8:59:00.993 (be careful to use the Gregorian leap rule if you want to calculate this manually).