NSFileWrapper Sometimes Changes Modification Date to the Past
Matteo Rattoti (via Christian Tietze):
This repository demonstrates a bug in
NSFileWrapper
where overwriting a file with the same content using-[NSFileWrapper writeToURL:options:originalContentsURL:error:]
sometimes causes the file’s modification date to be set in the past instead of updating to the current time.
I think I saw someone speculate that this is due to it not using a nanosecond-capable date/time API—which would imply that this only happens on APFS—but I can’t seem to find the post.
Update (2025-03-12): Mark Rowe:
I mentioned on Slack that
struct stat
returns modification times as atimespec
which has ns resolution. Foundation sets modification times usingutimes
which represents times astimeval
which only has μs resolution. Foundation also explicitly rounds the ns portion of the timestamp to μs rather than truncating. I’m not sure why it doesn’t useutimensat
instead. That takes atimespec
and so should allow ns resolution when setting the modification time.
1 Comment RSS · Twitter · Mastodon
The comment about nanosecond-precision was made by Mike Rowe in AppKit Abusers Slack:
I think this is a consequence of the API used to read creation / access / modification times supporting nanosecond resolution, but the API used to set the modification time only supporting microsecond resolution
I guess something in Foundation may need to switch to utimensat from utimes
https://github.com/swiftlang/swift-foundation/blob/main/Sources/FoundationEssentials/FileManager/FileManager%2BFiles.swift#L928-L937 – that rounds the floating point portion of the time interval when converting to microseconds which is why it passes as often as it does