Skip to the content
KyleDunkerley DotPro

KyleDunkerley DotPro

Azure | Systems Engineer | Microsoft Certified

Connect on LinkedIn
Menu
  • About
  • Experience
  • Qualifications
  • Blog
May 04 2025
0

Update Photo Timezone

By Kyle

The Problem

You’re on holiday, in some exotic location, and forget to set your fancy camera to the correct timezone. You have the correct time on the camera, so away you go, snapping photo after photo. If the time is correct, surely the timezone will be correct right?

Only to discover when you get back home that, oh dear, your time zone was set to your home country all along, and now if you try update the timezone of your photos it changes the time it was taken. Luckily I have encountered this issue, and found a fix using ExifTool and handy-dandy, good ole PowerShell. The script (along with other tools) can be found on my GitHub where you can take it and use it to your hearts content.

What This Script Does

This PowerShell script makes working with photo metadata super easy. First, it installs ExifTool and ensures it’s properly set up in your system PATH variables—this step is crucial so you can run ExifTool from anywhere in the command line. Once installed, the script takes care of your photos by updating their timezone metadata while keeping the original timestamps intact.

How It Works

The script starts by grabbing ExifTool via WinGet, checking if it’s installed, and adding it to your system’s PATH if needed. Then, it scans a folder you specify, pulling all .jpg files—though you can tweak this to include formats like .dng, .raw, and .cr2 if needed. After making sure the folder exists, it loops through each image, checking its original timestamp and timezone. If the timezone is already correct, it skips the file; otherwise, it adjusts the timezone based on Melbourne’s daylight saving periods, applies the update, and ensures everything stays properly synchronized. The script even cleans up leftover temporary files and adds an overwrite protection to prevent metadata issues. Finally, it prints success messages, confirming that all photos have been updated smoothly.

The Script

And now to the actual code.
How exciting!

I am using a plugin that colourizes this for easy reading – its not perfect, hence why some comments are not coloured correctly. But if you copy this into VSCode, it will sort it out for you.

#############################################################################
#
# Photo Metadata Editor - Update TimeZones Using exiftool
# (PME_exif)
#
# Description: 
# Updates the exif metadata of each photo to reflect the correct timezone
# while keeping the date and time of the original photo
#
# Author: Kyle Dunkerley
# Date: 02/05/2025
# 
#############################################################################

# -------  Change these values for your use case -------  #

# Define the folder containing your photos
$folderPath = "Path_to_folder"

# The timezone to update to
# EG: Australia is +10:00 for AEDT and +11:00 for AEST
# For this one, I have used Veitnam ($timezone)
$timeZone = "$timezone"


# -------  The script -------  #
# Change nothing under this line unless you like tinkering

# Install ExifTool via WinGet
winget install --id PhilHarvey.ExifTool -e

# Define the expected installation path
$ExifToolPath = "C:\Program Files\ExifTool"

# Verify the installation
if (!(Test-Path $ExifToolPath)) {
    Write-Host "ExifTool installation path not found. Check manually."
    exit
}

# Get current system path variables
$CurrentPath = [System.Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine)

# Check if ExifTool is already in the path
if ($CurrentPath -like "*$ExifToolPath*") {
    Write-Host "ExifTool is already in the system PATH."
} else {
    # Append ExifTool path to system variables
    $NewPath = "$CurrentPath;$ExifToolPath"
    [System.Environment]::SetEnvironmentVariable("Path", $NewPath, [System.EnvironmentVariableTarget]::Machine)
    
    Write-Host "ExifTool has been added to the system PATH."
}

# Verify by checking the version
Write-Host "Verifying ExifTool installation..."
Start-Process -NoNewWindow -Wait -FilePath "exiftool" -ArgumentList "-ver"

# Check if folder exists
if (-not (Test-Path $folderPath)) {
    Write-Host "`ERROR: Folder path does not exist: $folderPath`" -ForegroundColor Red
    exit
}

# Get all JPG files in the folder
$jpgFiles = Get-ChildItem -Path $folderPath -Filter "*.jpg" -File


# Process each image file
foreach ($file in $jpgFiles) {
    Write-Host "Processing $($file.FullName)"

    try {
        # Delete any lingering ExifTool temporary files
        Remove-Item "$($file.FullName)_exiftool_tmp" -ErrorAction SilentlyContinue

        # Read original timestamp and timezone offset
        $dateTaken = & $exifToolPath -DateTimeOriginal -S -s -d "%Y:%m:%d %H:%M:%S" "$($file.FullName)"
        $offsetTimeOriginal = & $exifToolPath -OffsetTimeOriginal -S -s "$($file.FullName)"

        # Ensure DateTimeOriginal is valid
        if ($dateTaken -eq $null -or $dateTaken -eq "") {
            Write-Host "ERROR: Skipping $($file.FullName) - No valid DateTimeOriginal found $resetText" -ForegroundColor Red
            continue
        }

        # Check if the photo is already set to the correct timezone
        if ($offsetTimeOriginal -eq $timeZone) {
            Write-Host "Skipping $($file.FullName) - Already set to $timeZone $resetText" -ForegroundColor Green
            continue
        }

        # Determine Melbourne timezone offset based on daylight saving period
        $dateTimeObj = [DateTime]::ParseExact($dateTaken, "yyyy:MM:dd HH:mm:ss", $null)
        $originalTimezone = if ($dateTimeObj.Month -ge 10 -or $dateTimeObj.Month -le 3) { "+11:00 (AEDT)" } else { "+10:00 (AEST)" }

        Write-Host "Original timestamp: $dateTaken | Original timezone: $originalTimezone"

        # Update timezone offset
        & $exifToolPath "-OffsetTimeOriginal=$timezone" "-OffsetTimeDigitized=$timezone" "$($file.FullName)"
        Write-Host "Updated timezone offset to $timezone for $($file.FullName)" -ForegroundColor Green

        # Sync metadata properly
        & $exifToolPath "-overwrite_original" "-P" "-XMP:all=IPTC:all" "$($file.FullName)"
        Write-Host "Metadata synchronized for $($file.FullName)" -ForegroundColor Green

        # Re-read the new timestamp
        $newTimestamp = & $exifToolPath -DateTimeOriginal -S -s -d "%Y:%m:%d %H:%M:%S" "$($file.FullName)"

        # Output new timestamp in green
        Write-Host "SUCCESS: New timestamp: $newTimestamp | New timezone: $timezone $resetText" -ForegroundColor Green
    
    } catch {
        Write-Host "ERROR: Failed to process $($file.FullName) - $_ $resetText" -ForegroundColor Red
    }
}

Write-Host "Processing complete. Changes applied using ExifTool, with full metadata sync. $resetText" -ForegroundColor Green

Using this script, your photos should now be in the correct timezone.
If you have any fixes, improvements, or comments, feel free to add to the script on GitHub!

Share this:

  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on X (Opens in new window) X

Like this:

Like Loading...
Posted inPowerShell
Tagsphoto metadata powershell timezone change

Leave a Reply Cancel reply

You must be logged in to post a comment.

Search

Proudly powered by WordPress | Theme: Futurio

Custom menu section

This is off canvas menu widget area. To enable it add some widgets into Appearance – Widgets – Menu Section, and go to Customizer – Main menu to set the icon position.

%d