Nikon stores wrong timestamp
I noticed the File Modification Date/Time timestamp is saved incorrectly on my Nikon D5600.
This is annoying, because when I copy my files to my phone, some tools order the photos by their mtime, and if it is set incorrectly, pictures won't be in order.
I shot a photo at 16:40:30 CEST (UTC+2). Note: My camera settings are set to Berlin time (UTC+1) with summer time enabled. Sync time via bluetooth is enabled.
1. The problem
Note: The commands below were executed after the file has been moved from the SD card to my ext4 file system.
I've moved them with Thunar, which usually keeps the timestamps as they are.
I'm on the 5.10.49-1-MANJARO
kernel and Thunar 4.16.8
.
This is what exiftool's output looks like:
$ exiftool DSC_8783-shot-at-16-40-cest.JPG | grep -i time
File Modification Date/Time : 2021:07:29 18:40:30+02:00
File Access Date/Time : 2021:07:29 16:41:09+02:00
File Inode Change Date/Time : 2021:07:29 16:41:38+02:00
Exposure Time : 1/60
Date/Time Original : 2021:07:29 16:40:29
Time Zone : +01:00
Power Up Time : 0000:00:00 00:00:00
Sub Sec Time : 87
Sub Sec Time Original : 87
Sub Sec Time Digitized : 87
GPS Time Stamp : 14:40:28.31
Date/Time Original : 2021:07:29 16:40:29.87
GPS Date/Time : 2021:07:29 14:40:28.31Z
So the File Modification Date/Time is just wrong. It should be either 2021:07:29 16:40:30+02:00 or 2021:07:29 18:40:30Z.
See the mtime from stat:
$ stat DSC_8783-shot-at-16-40-cest.JPG
Datei: DSC_8783-shot-at-16-40-cest.JPG
Größe: 7027908 Blöcke: 13728 EA Block: 4096 reguläre Datei
Gerät: 10302h/66306d Inode: 2887230 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 1000/ neonew) Gid: ( 1000/ neonew)
Zugriff: 2021-07-29 16:41:09.435963000 +0200
Modifiziert: 2021-07-29 18:40:30.000000000 +0200
Geändert: 2021-07-29 16:41:38.542630557 +0200
Geburt: 2021-07-29 16:41:09.435963322 +0200
$ stat -c "Filename : %n
atime : %x
mtime : %y
ctime : %z
" DSC_8783-shot-at-16-40-cest.JPG
Filename : DSC_8783-shot-at-16-40-cest.JPG
atime : 2021-07-29 16:41:09.435963000 +0200
mtime : 2021-07-29 18:40:30.000000000 +0200
ctime : 2021-07-29 16:51:29.019308742 +0200
On the SD card with a FAT32 file system the output looks like this:
$ stat DSC_8783.JPG
Datei: DSC_8783.JPG
Größe: 7027908 Blöcke: 13728 EA Block: 32768 reguläre Datei
Gerät: b301h/45825d Inode: 345 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 1000/ neonew) Gid: ( 1000/ neonew)
Zugriff: 2021-07-29 02:00:00.000000000 +0200
Modifiziert: 2021-07-29 18:46:10.000000000 +0200
Geändert: 2021-07-29 18:46:10.000000000 +0200
Geburt: -
2. The fix: Set mtime to exif timestamp
I don't really know how to fix the timestamp on the file system, e.g. by changing a setting in the camera or copying the file in a different way.
That's why I use this command to set the ctime of the file to the DateTimeOriginal from the exif data. I do it right after I move the files from the SD card, so I know I have not changed them before.
Note: This might lose information, so be careful applying this command.
2.1. First attempt
Second note: Your file must have exif information and a DateTimeOriginal field set. If your file does not have the field, exiftool will output No writable tags set and won't change the timestamp (which is great).
exiftool "-FileModifyDate<DateTimeOriginal" DSC_8783-shot-at-16-40-cest.JPG
If you want to change the dates by a fixed time interval, you can also use this alternative:
exiftool "-FileModifyDate+=1:12:28 14:54:32" -verbose DSC_8783-shot-at-16-40-cest.JPG
This will add 1 year, 12 month, 28 days, 14 hours, 54 minutes, 32 seconds.
2.2. Second attempt
The command above has a problem though: It also updates the atime. If you don't want that, use this command:
touch -m -t `exiftool -s3 -d "%Y%m%d%H%M.%S" -DateTimeOriginal DSC_7947.JPG` DSC_7947.JPG
# # for all files in directory
for f in DSC_*.JPG ; do touch -m -t `exiftool -s3 -d "%Y%m%d%H%M.%S" -DateTimeOriginal "$f"` "$f" ; done
# recursively
find . -iname "DSC_*.jpg" -type f -exec sh -c 'touch -m -t $(exiftool -s3 -d "%Y%m%d%H%M.%S" -DateTimeOriginal "$1") "$1"' sh {} \;
3. Manually update mtime
The ctime is controlled by Linux so you cannot easily change it. And you don't really need to.
What you can change is the mtime (last modification date):
touch -m -d "5 hours ago" image.jpg
touch -m -d "2007-01-31T08:46:26+02:00" image.jpg
4. Timezone issues
On the second command, touch saves the time as 2007-01-31 07:46:26 +0100
,
so it still converts the timezone to +01:00.
That's because in January 2007 there was CET in Berlin, not CEST (summer time).
touch should respect the TZ environment variable, and it does, but it
still converts the timezone. :(
I could not find a fix for this. It does not hurt that much, because the time is still correct for sorting etc.
Btw: Here is how you can check your current timezone:
date +"%Z %z"
# Outputs 'CEST +0200' on my system
TZ=America/Havana date +"%Z %z"
# Outputs 'CDT -0400'
5. The other way round: Set exif timestamp to mtime
If you want to set the DateTimeOriginal exif field on a file without exif data, and you want to use the mtime as source, you can run this:
exiftool "-DateTimeOriginal<FileModifyDate" "-FileModifyDate<FileModifyDate" no-exif.jpg
Note: This will also update the atime.