Our camera’s clock got reset and we didn’t notice until we had shot nearly two hundred photos. Doh! Even after we figured out the offset required to correct the problem, it turned out to be a bit involved to apply it. I ended up writing a Ruby script to do it. Then I was able to correct both the filesystem dates as well as the embedded EXIF timestamps for all the images with the following command:
camera_date.rb “18 Jan 2005 23:31:12″ “14 Sep 2009 11:31:12″ *.PEF
The first time stamp is the incorrect time stamp of one of the images, and the second is the correct time stamp for that particular image. This offset is then applied to all the specified files (*.PEF). The Ruby script is below. It requires that ExifTool be installed.
#!/usr/bin/env ruby
require 'time'
# 2009-10-17 LHN: Adjust file modification time and EXIF fields of files.
# Used to correct files that were recorded on a camera that had it's clock
# accidentally reset.
# Requires ExifTool (http://www.sno.phy.queensu.ca/~phil/exiftool)
def help_message
puts <<HEREDOC
Camera Date rev 2009-10-18
Camera Date is intended to correct images take on cameras whose clocks were
accidentally reset. It will update the following pieces of information:
* filesystem timestamp
* EXIF fields DateTimeOriginal, CreateDate, ModifyDate, Date
Syntax is camera_date.rb bad_date good_date file ...
bad_date is the date of an image as recorded by the camera
good_date is the correct date for that image
bad_date and good_date are used to calculate an ofset that can then be applied
to all specified files.
dates are specified in RFC8288 format and must be surrounded by quotes.
Example:
camera_date.rb "18 Jan 2005 22:10:03" "14 Sep 2009 10:10:03" IMGP7843.PEF IMGP7845.PEF
HEREDOC
exit
end
help_message unless ARGV.length >= 3
begin
INPUT_DATE = Time.parse(ARGV[0])
OUTPUT_DATE = Time.parse(ARGV[1])
OFFSET_TOTAL_SECS = OUTPUT_DATE.to_i - INPUT_DATE.to_i
puts "#{INPUT_DATE} => #{OUTPUT_DATE}"
puts "Offset in seconds is #{OFFSET_TOTAL_SECS}"
ARGV[2 .. -1].each{ |entry|
mtime = File.stat(entry).mtime
newtime = mtime + OFFSET_TOTAL_SECS
puts "#{entry}: #{mtime} -> #{newtime}"
system("exiftool \"-AllDates=#{newtime.strftime("%Y:%m:%d %H:%M:%S")}\" \"-Date=#{newtime.strftime("%Y:%m:%d")}\" #{entry}")
system("touch -c -t#{newtime.strftime("%Y%m%d%H%M.%S")} #{entry}")
}
puts "Done."
rescue StandardError => e
puts e
help_message
end