ExifTool for Google Takeout: Commands to Fix the Dates (Tested)
Tested exiftool commands that copy photoTakenTime and GPS from Google Takeout .json files into your photos, fix file dates on Windows, and handle the cut-off names.
ExifTool can fix a Google Takeout export for free. One command copies photoTakenTime from each .json sidecar into the photo's DateTimeOriginal and file date, and four more arguments add the GPS position. It works on most photos. It misses cut-off sidecar names, (1) duplicates, -edited copies and videos unless you add the extra steps below. Every command on this page was tested with ExifTool 13.59 on a sample Takeout folder.
If you would rather not use a command line, skip to the GUI options at the end of this page.
The problem the commands solve
Google Takeout gives you each photo next to a small .json file:
IMG_1234.jpg
IMG_1234.jpg.supplemental-metadata.json
The sidecar holds the real date taken as photoTakenTime.timestamp, a number of seconds since 1970 in UTC, and the location as geoData.latitude and geoData.longitude. Many photos, such as screenshots, chat images and anything you re-dated in Google Photos, have no date inside the file at all. Your computer shows the download day instead. ExifTool reads JSON files and exposes those values as tags: PhotoTakenTimeTimestamp, GeoDataLatitude, GeoDataLongitude and Description.
Exports from before 2024 name the sidecar IMG_1234.jpg.json. Newer ones use .supplemental-metadata.json. Supplemental-metadata.json explained covers the format.
Step 1: Install ExifTool
- Windows: download the Windows zip from exiftool.org, unpack it, and rename
exiftool(-k).exetoexiftool.exe. Put it in a folder on your PATH, or in the folder that holdsTakeout. - Mac:
brew install exiftool, or the installer package from exiftool.org. - Linux:
sudo apt install libimage-exiftool-perl(Debian, Ubuntu) orsudo dnf install perl-Image-ExifTool(Fedora).
Check it with exiftool -ver.
Step 2: Unzip every part into one folder
ExifTool cannot read inside zip files. Unzip all Takeout parts into the same folder, so you get one Takeout/Google Photos folder. A photo and its sidecar are often in different parts. Google Takeout zip files shows how.
Work on a copy the first time. ExifTool writes into your files.
Step 3: Rename the sidecars ExifTool cannot find
The main command finds each sidecar by building its name from the photo's name. Three kinds of sidecar break that, and in a real export they are hundreds of files. This Bash script (Mac Terminal, Linux, or Git Bash and WSL on Windows) renames them to the standard name first. Run it in the folder that holds Takeout:
cd "Takeout/Google Photos"
# 1. Duplicates: IMG_1234.jpg.supplemental-metadata(1).json -> IMG_1234(1).jpg.supplemental-metadata.json
find . -name '*(*).json' | while IFS= read -r j; do
n=$(echo "$j" | sed -E \
-e 's/\.([A-Za-z0-9]+)\.supplemental-metadata\(([0-9]+)\)\.json$/(\2).\1.supplemental-metadata.json/' \
-e 's/\.([A-Za-z0-9]+)\(([0-9]+)\)\.json$/(\2).\1.json/')
[ "$n" != "$j" ] && mv -n "$j" "$n"
done
# 2. Cut-off names: Google cuts the sidecar name at 46 characters before .json
find . -type f ! -name '*.json' | while IFS= read -r p; do
[ -e "$p.supplemental-metadata.json" ] || [ -e "$p.json" ] && continue
f="$(basename "$p").supplemental-metadata"
c="$(dirname "$p")/${f:0:46}.json"
[ -e "$c" ] && mv -n "$c" "$p.supplemental-metadata.json"
done
# 3. Old style: IMG_1234.jpg.json -> IMG_1234.jpg.supplemental-metadata.json
find . -type f -name '*.json' ! -name '*.supplemental-metadata.json' ! -name 'metadata.json' | while IFS= read -r j; do
p="${j%.json}"
[ -e "$p" ] && [ ! -e "$p.supplemental-metadata.json" ] && mv -n "$j" "$p.supplemental-metadata.json"
done
cd ../..
After this, almost every sidecar is called <photo name>.supplemental-metadata.json, so one command pattern finds them all. mv -n never overwrites a file. ExifTool and supplemental-metadata.json explains each case.
On Windows without Bash, you can skip this step. The main command still fixes every photo whose sidecar has the standard name, and Step 7 lists the rest.
Step 4: Copy the date and GPS into the photos
This is the main command, for the Mac and Linux terminal:
TZ=Europe/Paris exiftool -r -d %s \
-tagsfromfile "%d/%F.supplemental-metadata.json" \
"-DateTimeOriginal<PhotoTakenTimeTimestamp" \
"-CreateDate<PhotoTakenTimeTimestamp" \
"-FileModifyDate<PhotoTakenTimeTimestamp" \
'-GPSLatitude<${GeoDataLatitude;$_=undef if $_==0}' \
'-GPSLatitudeRef<${GeoDataLatitude;$_=undef if $_==0}' \
'-GPSLongitude<${GeoDataLongitude;$_=undef if $_==0}' \
'-GPSLongitudeRef<${GeoDataLongitude;$_=undef if $_==0}' \
-ext jpg -ext jpeg -ext png -ext heic -ext gif \
-overwrite_original "Takeout/Google Photos"
What each part does:
TZ=Europe/Parissets the time zone used to turn the UTC timestamp into a local time. Use the zone where most of your photos were taken. See the time zone section below.-rincludes every subfolder.-d %stells ExifTool the value it reads is a count of seconds.-tagsfromfile "%d/%F.supplemental-metadata.json"names the sidecar:%dis the photo's folder,%Fits full file name.- The three date lines write the date taken, the EXIF create date and the file's modified date.
- The four GPS lines copy the position. The
$_=undef if $_==0part skips photos that Google gave0.0, which means "no location". Without it, those photos land in the sea off West Africa. ExifTool sets N/S and E/W from the sign of the number. -overwrite_originalstops ExifTool from leaving an_originalcopy of every file.
In our test, a photo with a timestamp of 10:05 UTC on 14 July 2019 got a date taken of 12:05, which is correct for Paris in summer. A photo with 0.0 coordinates got its date and no GPS, and the others got the right position.
Warnings such as "Error opening file ... supplemental-metadata.json" mean a photo has no sidecar under that name. Those are the files Step 7 finds.
On Windows: the same in Command Prompt
Open Command Prompt in the folder that holds Takeout and paste this as one line:
exiftool -r -d %s -tagsfromfile "%d/%F.supplemental-metadata.json" "-DateTimeOriginal<PhotoTakenTimeTimestamp" "-CreateDate<PhotoTakenTimeTimestamp" "-FileModifyDate<PhotoTakenTimeTimestamp" "-FileCreateDate<PhotoTakenTimeTimestamp" "-GPSLatitude<${GeoDataLatitude;$_=undef if $_==0}" "-GPSLatitudeRef<${GeoDataLatitude;$_=undef if $_==0}" "-GPSLongitude<${GeoDataLongitude;$_=undef if $_==0}" "-GPSLongitudeRef<${GeoDataLongitude;$_=undef if $_==0}" -ext jpg -ext jpeg -ext png -ext heic -ext gif -overwrite_original "Takeout\Google Photos"
What differs from the Mac version:
-FileCreateDatesets the Date created that File Explorer shows. It only exists on Windows (and on a Mac).- Command Prompt needs double quotes everywhere. In PowerShell, use single quotes around the GPS arguments instead, because PowerShell reads
$_itself. - ExifTool uses the PC's time zone setting. Set Windows to the zone where most photos were taken before you run it.
- In a
.batfile, write%%d,%%Fand%%sinstead of%d,%Fand%s.
We could not run this on Windows for this article; the Windows-only part is -FileCreateDate, which is documented to work there.
Step 5: Edited copies
IMG_1234-edited.jpg has no sidecar. It shares the original's. Once the originals are done, copy the date and GPS from each original:
find "Takeout/Google Photos" -name '*-edited.*' | while IFS= read -r f; do
exiftool -tagsfromfile "${f/-edited/}" -DateTimeOriginal -CreateDate -FileModifyDate -GPS:all -overwrite_original "$f"
done
Step 6: Videos
MP4 and MOV files keep their dates in QuickTime tags, which are stored in UTC. -api QuickTimeUTC tells ExifTool to convert correctly:
exiftool -r -d %s -api QuickTimeUTC \
-tagsfromfile "%d/%F.supplemental-metadata.json" \
"-CreateDate<PhotoTakenTimeTimestamp" "-ModifyDate<PhotoTakenTimeTimestamp" \
"-TrackCreateDate<PhotoTakenTimeTimestamp" "-MediaCreateDate<PhotoTakenTimeTimestamp" \
"-FileModifyDate<PhotoTakenTimeTimestamp" \
-ext mp4 -ext mov -overwrite_original "Takeout/Google Photos"
On Windows, add "-FileCreateDate<PhotoTakenTimeTimestamp" and put it on one line. Live Photo clips usually have no sidecar; see Live Photos in Takeout.
Step 7: Find what is still undated
exiftool -r -if 'not $DateTimeOriginal' -p '$Directory/$FileName' -ext jpg -ext jpeg -ext png -ext heic "Takeout/Google Photos"
This prints every photo that still has no date taken. On Windows, use double quotes around the condition and the -p text. What is left is usually photos with no sidecar at all (some photos have no JSON) and odd names you match by hand.
Optional: the caption
The description you typed in Google Photos is in the sidecar too:
exiftool -r -tagsfromfile "%d/%F.supplemental-metadata.json" "-ImageDescription<Description" "-XMP-dc:Description<Description" -ext jpg -ext heic -P -overwrite_original "Takeout/Google Photos"
-P keeps the file date you set in Step 4. Any later ExifTool command that writes into the photos resets the file's modified date to now unless you add -P.
The time zone trap
The sidecar holds an exact moment in UTC. DateTimeOriginal holds a wall-clock time with no zone. ExifTool turns one into the other using your computer's zone at the time you run it. A photo taken at 12:05 in Paris comes out as 12:05 if the computer is set to Paris, and as 06:05 if it is set to New York. Photos from trips in other zones will be off by the difference. The sidecar alone cannot tell you the local time, so there is no perfect fix. If you want to leave photos that already have a camera date alone, add -if 'not $DateTimeOriginal' to the Step 4 command. See photo date off by hours.
The GUI options
If the steps above look like an evening of work, they are. There are two ways to get the same result without typing commands.
For a Google Takeout export: Takeout JSON Metadata Fixer (Windows and Mac). You drop in the zip files. It matches every photo to its sidecar, including the cut-off names, (1) duplicates, edited copies, videos and Live Photo clips, and writes the date taken, the GPS position and the file dates. It can also sort into Year/Month folders and rename by date in the same run, with a dry run first. It runs offline. The first 500 photos are free; Premium is $19.99 once.
For any photos, not just Takeout: the same app. Takeout JSON Metadata Fixer for Windows has a Selected Photos tab. You choose a library folder, select photos and press Edit, then set the date taken, shift times, fix the time zone, read the date from the file name, set the file dates or put a location on a map. It uses ExifTool inside, and every change can be undone. The first 100 edits are free, and the same Premium unlocks the rest. If you only want the editing part, there is also a smaller editing-only app, Photo Date & Metadata Editor. See ExifTool GUI for Windows for how it compares with the free ExifToolGUI.
Frequently asked questions
ExifTool says "No writable tags set from" a sidecar. What does that mean?
The sidecar was found but gave nothing to write, or the name pattern pointed at a file that does not exist. Album metadata.json files cause this too and can be ignored.
Does ExifTool work on the zip files?
No. Unzip every part into one folder first.
Does writing the date reduce the photo's quality?
No. ExifTool rewrites the metadata and leaves the image data untouched.
Should I use photoTakenTime or creationTime?
photoTakenTime. creationTime is when the photo was uploaded to Google, often years later.
Why use -if on the target and not on the JSON?
An -if condition is tested on the photo being written, not on the sidecar. That is why the GPS commands above filter the 0.0 values inside the copy argument instead.