Find photos by time zone

photos

Some of my photos in Apple Photos 2.0 (3150.4.120) have the wrong time zone, but I don't know which ones. I can find the time zone for an individual photo, by selecting Image > Adjust Date and Time.

But how can I find all photos with a certain time zone? I've tried searching in the Finder, in the photos' filesystem metadata (using mdls), in the photos' EXIF metadata (using exiftool), and even in the Photos sqlite database, but haven't found where it's stored.

Where is this information?

Best Answer

It may depend on the camera/phone and OS; but, I don't think the timezone is explicitly stored in the picture's EXIF metadata.

In some metadata, there is a GPS Time (Atomic Clock) which is set to UTC. So, Photos probably just calculates the offsets of Date and Time (Original) to display the timezone.

You may be able to use exiftool to build a list of those two times for your pictures, and search for outliers which are more (or less) different than the others.

Update from original poster:

I threw together a quick Python script to compare these times, and print the ones that aren't in the expected time zone, or have different values for minutes. You'll need to export the unmodified originals from Photos, since the modified ones don't have this metadata, and then pass their filenames to this script.

Of course, I have no idea if this is anything close to what Photos does to set the time zone. But it correctly identified the photos that I knew of with the wrong time zone, and didn't find any false positives.

#!/usr/bin/python

from subprocess import check_output
import sys, re, os
from dateutil.parser import parse
from datetime import datetime

expected_offset_hours = 8.0  # set to appropriate time zone offset

def get_field(out, name):
    match = re.search("^" + re.escape(name) + "\t(.+?)$", out, re.MULTILINE)
    if match:
        return match.group(1)
    return None

for arg in sys.argv[1:]:
    if not os.path.exists(arg):
        continue
    out = check_output(["exif", "-m", arg])
    gps_date = get_field(out, "GPS Date")
    gps_time = get_field(out, "GPS Time (Atomic Clock)")
    if gps_date == None or gps_time == None:
        print arg + "\tNo GPS date/time"
        continue
    gps_parsed = datetime.strptime(gps_date + " " + gps_time, '%Y:%m:%d %H:%M:%S.%f')
    orig_datetime = get_field(out, "Date and Time (Original)")
    if orig_datetime == None:
        continue
    orig_parsed = datetime.strptime(orig_datetime, '%Y:%m:%d %H:%M:%S')
    offset_secs = (orig_parsed - gps_parsed).total_seconds()
    offset_hours = round(offset_secs / 3600)
    offset_mins = abs(offset_secs - (offset_hours * 3600)) // 60
    if offset_hours != expected_offset_hours or offset_mins > 0:
        #print gps_date + ' ' + gps_time + ' ' + str(gps_parsed)
        #print orig_datetime + ' ' + str(orig_parsed)
        print arg + "\t" + str(offset_hours) + "\t" + str(offset_mins)