Install Exiftool
BASH
sudo apt install libimage-exiftool-perl
Run this Python Script
BASH
import os
import json
import subprocess
from datetime import datetime

# The root directory to scan (current directory)
root_dir = "."

def update_media_file(file_path, json_path):
    try:
        with open(json_path, 'r') as f:
            data = json.load(f)
        
        # Extract timestamp from Ente's JSON format
        # Key path: photoTakenTime -> timestamp
        timestamp = int(data.get('photoTakenTime', {}).get('timestamp', 0))
        
        if timestamp == 0:
            print(f"[SKIP] No timestamp found in JSON for: {file_path}")
            return

        # Convert epoch to formatted date string for ExifTool
        # Format: YYYY:MM:DD HH:MM:SS
        dt_object = datetime.fromtimestamp(timestamp)
        formatted_date = dt_object.strftime("%Y:%m:%d %H:%M:%S")
        
        print(f"[PROCESSING] {file_path} -> {formatted_date}")

        # Construct ExifTool command
        # We update:
        # 1. DateTimeOriginal (Standard EXIF)
        # 2. CreateDate (Standard EXIF)
        # 3. MediaCreateDate (For Video)
        # 4. FileModifyDate (The actual file system time - vital for Immich backups)
        
        cmd = [
            "exiftool",
            "-overwrite_original",
            "-q", # Quiet mode
            f"-DateTimeOriginal={formatted_date}",
            f"-CreateDate={formatted_date}",
            f"-MediaCreateDate={formatted_date}",
            f"-TrackCreateDate={formatted_date}",
            f"-FileModifyDate={formatted_date}",
            file_path
        ]
        
        subprocess.run(cmd, check=True)

    except Exception as e:
        print(f"[ERROR] Could not process {file_path}: {e}")

def main():
    # Walk through all directories
    for subdir, dirs, files in os.walk(root_dir):
        # Skip the 'metadata' folders themselves so we don't process JSONs
        if 'metadata' in subdir:
            continue

        for filename in files:
            # Only process images and videos
            if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.mp4', '.mov', '.heic')):
                file_path = os.path.join(subdir, filename)
                
                # specific logic for Ente structure:
                # Image: ./Camera/IMG1.jpg
                # JSON:  ./Camera/metadata/IMG1.jpg.json
                
                json_filename = f"{filename}.json"
                json_path = os.path.join(subdir, "metadata", json_filename)
                
                if os.path.exists(json_path):
                    update_media_file(file_path, json_path)
                else:
                    print(f"[MISSING JSON] Could not find metadata for: {filename}")

if __name__ == "__main__":
    main()