How to Change image captured date in python?

No real need to write Python, you can do it in one line in the Terminal using jhead. For example, adjust all EXIF times forward by 1 hour

jhead -ta+1:00 *.jpg

Make a COPY of your files and test it out on that first!

Download from here.


This is quite easy to do using the piexif library:

from datetime import datetime
import piexif

filename = 'image.jpg'
exif_dict = piexif.load(filename)
new_date = datetime(2018, 1, 1, 0, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date
exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date
exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, filename)

This script will insert the new date 2018:01:01 00:00:00 into the DateTime, DateTimeOriginal and DateTimeDigitized EXIF fields for image.jpg.


PNG does not support EXIF so I made this to fix the creation/modification time instead, based on Wilbur Dsouza's answer:

import datetime
import os
import re
import sys
import time

import piexif


def fix(directory):
    print(directory)
    for dirpath, _, filenames in os.walk(directory):
        for f in filenames:
            fullPath = os.path.abspath(os.path.join(dirpath, f))
            # Format: Screenshot_20170204-200801.png
            if re.match(r"^Screenshot_\d\d\d\d\d\d\d\d-\d\d\d\d\d\d.*", f):
                match = re.search("^Screenshot_(\d\d\d\d)(\d\d)(\d\d)-(\d\d)(\d\d)(\d\d).*", f)
                year = int(match.group(1))
                month = int(match.group(2))
                day = int(match.group(3))
                hour = int(match.group(4))
                minute = int(match.group(5))
                second = int(match.group(6))

                date = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
                modTime = time.mktime(date.timetuple())

                print(f, date)

                os.utime(fullPath, (modTime, modTime))


if __name__ == "__main__":
    fix(sys.argv[1]) 

I might be late to this party, but i wrote a python script for bulk changing taken time field for whatsapp photos based on filename format Eg: IMG-20160117-WA0001.jpg. Also this does not overwrite the existing properties. https://github.com/dsouzawilbur/Scripts/blob/master/Change_Photo_Taken_Time.py

from datetime import datetime
import os
import re
import piexif

def absoluteFilePaths(directory):
    for dirpath,_,filenames in os.walk(directory):
        for f in filenames:
            fullPath = os.path.abspath(os.path.join(dirpath, f))
            if re.match(r"^IMG-\d\d\d\d\d\d\d\d-WA\d\d\d\d.*", f) and not re.match(r"^IMG-\d\d\d\d\d\d\d\d-WA\d\d\d\d-ANIMATION.gif", f):
                print(f+" Matched")
                match = re.search("^IMG-(\d\d\d\d)(\d\d)(\d\d)-WA\d\d\d\d.*", f)
                year = match.group(1)
                month= match.group(2)
                day = match.group(3)
                exif_dict = piexif.load(fullPath)
                #Update DateTimeOriginal
                exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                #Update DateTimeDigitized               
                exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                #Update DateTime
                exif_dict['0th'][piexif.ImageIFD.DateTime] = datetime(int(year), int(month), int(day), 4, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
                exif_bytes = piexif.dump(exif_dict)
                piexif.insert(exif_bytes, fullPath)
                print("############################")


absoluteFilePaths("__DIRECTORY_WITH_PHOTOS__")