#------------------------------------------------------------------------------
# File:         time_zone.config
#
# Description:  ExifTool config file to return time zone from an image
#
# Notes:        The Composite:TimeZone tag defined here attempts to determine
#               the time zone for an image.  If possible, the camera time zone
#               is used, if that does not exist, the time zone for
#               DateTimeOriginal is returned, but if this can't be determined
#               then the time zone for CreateDate and then ModifyDate are used.
#               If this all does not result in a time zone, the timezone of the
#               TimeCreated tag is used
#
# Usage:        exiftool -config time_zone.config -timezone FILE
#
# Requires:     ExifTool version 7.74 or later
#
# Revisions:    2016/10/03 - P. Harvey Created
#               2016/12/12 - H. Baan Corrected tag name, added support for
#                            camera time zone/daylight savings info in
#                            MakerNotes
#               2017/01/05 - H. Baan Handle case were GPSDateStamp is missing
#               2017/01/06 - H. Baan Use QuickTime:CreationDate if available
#               2017/03/12 - H. Baan Added QuickTime:TimeZone, reordered
#                            Desired tags according to precedence, added
#                            comments
#------------------------------------------------------------------------------

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        # Calculate the TimeZone of the picture taken
        TimeZone => {
            Desire => {
                # TimeZone information tags ordered by precedence
                0 => 'MakerNotes:TimeZone',
                1 => 'MakerNotes:DaylightSavings',
                2 => 'QuickTime:TimeZone',
                3 => 'OffsetTimeOriginal',
                4 => 'OffsetTimeDigitized',
                5 => 'OffsetTime',
                6 => 'TimeZoneOffset',
                7 => 'GPSDateStamp',
                8 => 'GPSTimeStamp',
                9 => 'DateTimeOriginal',
                10 => 'DateTimeDigitized',
                11 => 'CreateDate',
                12 => 'ModifyDate',
                13 => 'QuickTime:CreationDate',
                14 => 'TimeCreated',
            },
            RawConv => q{
                # TimeZone from MakeNotes (camera setting)
                return TimeZoneString($val[0] + ($val[1] ? 60 : 0)) if defined $val[0];

                # TimeZone from QuickTime (camera setting)
                return TimeZoneString($val[2]) if $val[2];

                # TimeZone from offset fields
                return $val[3] if $val[3]; # DateTimeOriginal
                return $val[4] if $val[4]; # DateTimeDigitized
                return $val[5] if $val[5]; # (ModifyDate)
                if (defined $val[6]) { # (ModifyDate)
                    my $tzh = $val[6];
                    $tzh =~ s/ .*//;
                    return TimeZoneString($tzh * 60);
                }

                # Difference between GPS and local time as TimeZone
                if (defined $val[8]) {
                    my $loc = $val[9] || $val[10] || $val[11] || $val[12];
                    if ($loc) {
                        my @loc = split /[: ]/, $loc;
                        my @gmt = split /[: ]/, ($val[7]||"$loc[0]:$loc[1]:$loc[2]") . " $val[8]";
                        my $tzm = 15 * sprintf("%.0f", (GetTimeZone([@loc[5,4,3,2]], [@gmt[5,4,3,2]])) / 15);
                        $tzm -= 1440 if $tzm > 840;
                        $tzm += 1440 if $tzm < -720;
                        return TimeZoneString($tzm);
                    }
                }

                # TimeZone from QuickTime Creation Date
                if ($val[13] && $val[13] =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([+-]\d{2})(\d{2})/) {
                   return TimeZoneString($1 * 60 + $2);
                }

                # Time Created
                if ($val[14] && $val[14] =~ /\d{6}([+-]\d{2})(\d{2})/) {
                   return TimeZoneString($1 * 60 + $2);
                }
                return undef;
            },
        },
    },
);

1;  #end
