How to set only the year on the Exif Date

128 Views Asked by At

I only like to set the year on my images without changing the month, day or time.

A linux bash command would be nice.

3

There are 3 best solutions below

0
StarGeek On BEST ANSWER

Depending upon exactly what you are doing, exiftool can do this in batch without a script.

If your files have the year offset by the same amount, then you can use the time shift feature to shift the time forward/backwards (see the -TAG[+-^]=[VALUE] option and ExifTool Date/Time Shift Module)

For example, to shift the year back by two years, you would use a command like

exiftool -AllDates-="2:0:0 0" /path/to/files/

And to reverse it

exiftool -AllDates+="2:0:0 0" /path/to/files/

AllDates is an exiftool shortcut that will edit the three major EXIF tags, DateTimeOriginal, DateTimeDigitized (called CreateDate by exiftool), and DateTime (called ModifyDate by exiftool). The 2:0:0 0 represents the Year Month Day and Hour to shift by, and Minutes and Seconds can be added after the hour. With a single number, exiftool defaults to shifting the Hour, so to shift the Year, Month, or Day, you have to put a space before the hour.

If you want to batch replace a specific year with an entirely different one without affecting any other file, it becomes a bit more complicated. Instead of shifting, the easiest option would be to use the -api Filter option to apply a RegEx to the values and then the -TagsFromFile option to copy the new values back into the file

For example, to change any file with a year of 2026 into 2024 without affecting the 2023/2022/etc files, you would use a command like

exiftool -api "Filter=s/2026/2024/" -TagsFromFile @ -AllDates /path/to/files/

These commands creates backup files. Add -overwrite_original to suppress the creation of backup files. Add -r to recurse into subdirectories.

0
Max On

I wrote the following python script.
Now I can run:
find . -iname "*.JPG" -type f -exec ./exif-set-year-only.py {} 1980 2>cp.err \;

#!/usr/bin/env python3

import sys
import os
from exif import Image, DATETIME_STR_FORMAT
from datetime import datetime

def main():
    if (len(sys.argv) - 1) != 2:
        print('usage: %s filename year' % sys.argv[0] )
        return 
    filename_in = sys.argv[1]
    new_year = int(sys.argv[2])
    path, fname = os.path.split(filename_in)
    filename_out = os.path.join(path, "modified_" + fname)
    print('reading: %s --> writing: %s' % (filename_in, filename_out))
    with open(filename_in, 'rb') as image_file:
        image = Image(image_file)
    datetime_original = datetime.strptime(image['datetime_original'], DATETIME_STR_FORMAT)
    new_datetime = datetime_original.replace(year=new_year)
    print('  changing: %s -->  %s'  % (datetime_original.strftime("%m/%d/%Y, %H:%M:%S.%f"), new_datetime.strftime("%m/%d/%Y, %H:%M:%S.%f")))
    image.datetime_original = new_datetime.strftime(DATETIME_STR_FORMAT)
    image.datetime_digitized = new_datetime.strftime(DATETIME_STR_FORMAT)
    image.datetime = new_datetime.strftime(DATETIME_STR_FORMAT)
    with open(filename_out, 'wb') as new_image_file:
        new_image_file.write(image.get_file())


if __name__ == "__main__":
    main()
0
user3344003 On

To do this correctly with your own programming, you are going to need to parse the EXIF stream.

You need look for an SOI marker, skip any COM markers, skip any APPn markers, until you hit the APP1 marker.

Then you are going to have search the TIF data in the APP1 marker for date tags. Then you overwrite the dates which are in 8-bit text format.

All this requires you to work your way through the EXIF and TIF standards. These are not complex (as the JPEG standard is).

Your shell command could end up corrupting a lot of JPEG files that are not in EXIF format.