Skip to content

Instantly share code, notes, and snippets.

@KingWaffleIII
Created August 11, 2025 15:21
Show Gist options
  • Save KingWaffleIII/232ec3c86ba872238a83026bf8b9bb25 to your computer and use it in GitHub Desktop.
Save KingWaffleIII/232ec3c86ba872238a83026bf8b9bb25 to your computer and use it in GitHub Desktop.
Changes Google Photos Takeout photos/videos EXIF and file metadata datetimes to the correct value from the supplemental metadata JSON file. Put in same dir as the photos/vids and exiftool.exe.
import os
import glob
import subprocess
import json
from datetime import datetime
def get_correct_datetime(file_path):
directory = os.path.dirname(file_path)
base = os.path.basename(file_path)
pattern = os.path.join(directory, base + ".*.json")
matches = glob.glob(pattern)
if matches:
with open(matches[0],) as f:
metadata = json.load(f)
wrong_format = metadata['photoTakenTime']['formatted'] # 10 Aug 2025, 23:06:42 UTC
correct_format = datetime.strptime(wrong_format[:-4], '%d %b %Y, %H:%M:%S') # Convert to datetime object
return correct_format.replace(second=0).strftime('%Y:%m:%d %H:%M')
return None
imgs = []
for ext in ('*.jpg', '*.jpeg', '*.png', '*.webp'):
imgs.extend(glob.glob(os.path.join(os.getcwd(), ext)))
vids = glob.glob(os.path.join(os.getcwd(), '*.mp4'))
for file in imgs:
try:
correct_datetime = get_correct_datetime(file)
if not correct_datetime:
print(f"No supplemental metadata JSON found for {file}, skipping.")
continue
check = subprocess.run(['exiftool.exe', '-j', '-CreateDate', file], capture_output=True, text=True)
metadata = json.loads(check.stdout)
if not metadata or 'CreateDate' not in metadata[0]:
subprocess.run(['exiftool.exe', '-overwrite_original', f'-AllDates={correct_datetime}', file])
subprocess.run(['exiftool.exe', '-overwrite_original',
f'-FileCreateDate={correct_datetime}',
f'-FileModifyDate={correct_datetime}', file])
print(f"Processed image: {file}\n")
except Exception as e:
print(f"Error processing image {file}: {e}\n")
for file in vids:
try:
correct_datetime = get_correct_datetime(file)
if not correct_datetime:
print(f"No supplemental metadata JSON found for {file}, skipping.")
continue
check = subprocess.run(['exiftool.exe', '-j', '-CreateDate', file], capture_output=True, text=True)
metadata = json.loads(check.stdout)
if not metadata or 'CreateDate' not in metadata[0]:
subprocess.run([
'exiftool.exe', '-overwrite_original',
f'-CreateDate={correct_datetime}',
f'-ModifyDate={correct_datetime}',
f'-TrackCreateDate={correct_datetime}',
f'-TrackModifyDate={correct_datetime}',
f'-MediaCreateDate={correct_datetime}',
f'-MediaModifyDate={correct_datetime}', file])
subprocess.run(['exiftool.exe', '-overwrite_original',
f'-FileCreateDate={correct_datetime}',
f'-FileModifyDate={correct_datetime}', file])
print(f"Processed video: {file}\n")
except Exception as e:
print(f"Error processing video {file}: {e}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment