Subject: | timegm should be called with 4-digit year |
See also https://rt.cpan.org/Public/Bug/Display.html?id=124508
man Time::Local says
Whenever possible, use an absolute four digit year instead.
With a detailed explanation about ambiguity of 2-digit years above that.
Please review/test/merge the attached patch (not tested)
Subject: | fix.patch |
Index: Image-ExifTool-10.55/lib/Image/ExifTool.pm
===================================================================
--- Image-ExifTool-10.55.orig/lib/Image/ExifTool.pm
+++ Image-ExifTool-10.55/lib/Image/ExifTool.pm
@@ -4959,7 +4959,6 @@ sub ConvertDateTime($$)
shift @a while @a > 6; # remove superfluous entries
unshift @a, 1 while @a < 3; # add month and day if necessary
unshift @a, 0 while @a < 6; # add h,m,s if necessary
- $a[5] -= 1900; # base year is 1900
$a[4] -= 1; # base month is 1
# parse %z and %s ourself (to handle time zones properly)
if ($fmt =~ /%[sz]/) {
@@ -5103,7 +5102,6 @@ sub GetUnixTime($;$)
$tzsec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
undef $isLocal; # convert using GMT corrected for specified timezone
}
- $tm[0] -= 1900; # convert year
$tm[1] -= 1; # convert month
@tm = reverse @tm; # change to order required by timelocal()
return $isLocal ? TimeLocal(@tm) : Time::Local::timegm(@tm) - $tzsec;
Index: Image-ExifTool-10.55/lib/Image/ExifTool/Geotag.pm
===================================================================
--- Image-ExifTool-10.55.orig/lib/Image/ExifTool/Geotag.pm
+++ Image-ExifTool-10.55/lib/Image/ExifTool/Geotag.pm
@@ -204,7 +204,7 @@ sub LoadTrackLog($$;$)
next;
} elsif (/^HFDTE(\d{2})(\d{2})(\d{2})/) {
my $year = $3 + ($3 >= 70 ? 1900 : 2000);
- $dateFlarm = Time::Local::timegm(0,0,0,$1,$2-1,$year-1900);
+ $dateFlarm = Time::Local::timegm(0,0,0,$1,$2-1,$year);
$nmeaStart = 'B' ;
$format = 'IGC';
next;
@@ -333,7 +333,7 @@ sub LoadTrackLog($$;$)
/^TP,D,\s*([-+]?\d+\.\d*),\s*([-+]?\d+\.\d*),\s*(\d+)\/(\d+)\/(\d{4}),\s*(\d+):(\d+):(\d+)/ or next;
$$fix{lat} = $1;
$$fix{lon} = $2;
- $time = Time::Local::timegm($8,$7,$6,$4,$3-1,$5-1900);
+ $time = Time::Local::timegm($8,$7,$6,$4,$3-1,$5);
DoneFix: $isDate = 1;
$$points{$time} = $fix;
push @fixTimes, $time;
@@ -353,7 +353,7 @@ DoneFix: $isDate = 1;
next unless @d == 3 and @t == 3;
@$fix{qw(lat lon alt track dir pitch roll)} = @parts[2,3,4,5,8,9,10];
# (add the seconds afterwards in case some models have decimal seconds)
- $time = Time::Local::timegm(0,$t[1],$t[0],$d[0],$d[1]-1,$d[2]-1900) + $t[2];
+ $time = Time::Local::timegm(0,$t[1],$t[0],$d[0],$d[1]-1,$d[2]) + $t[2];
# set necessary flags for extra available information
@$has{qw(alt track orient)} = (1,1,1);
goto DoneFix; # save this fix
@@ -398,7 +398,7 @@ DoneFix: $isDate = 1;
$fix{track} = $12 if length $12;
my $year = $15 + ($15 >= 70 ? 1900 : 2000);
$secs = (($1 * 60) + $2) * 60 + $3;
- $date = Time::Local::timegm(0,0,0,$13,$14-1,$year-1900);
+ $date = Time::Local::timegm(0,0,0,$13,$14-1,$year);
#
# NMEA GGA sentence (no date)
#
@@ -441,7 +441,7 @@ DoneFix: $isDate = 1;
# $GPZDA,hhmmss.ss,DD,MM,YYYY,tzh,tzm (hhmmss in UTC)
/^\$GPZDA,(\d{2})(\d{2})(\d{2}(\.\d*)?),(\d+),(\d+),(\d+)/ or next;
$secs = (($1 * 60) + $2) * 60 + $3;
- $date = Time::Local::timegm(0,0,0,$5,$6-1,$7-1900);
+ $date = Time::Local::timegm(0,0,0,$5,$6-1,$7);
#
# Magellan eXplorist PMGNTRK (Proprietary MaGellaN TRacK) sentence (optional date)
#
@@ -457,7 +457,7 @@ DoneFix: $isDate = 1;
next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year
# optional date is available in PMGNTRK sentence
my $year = $15 + ($15 >= 70 ? 1900 : 2000);
- $date = Time::Local::timegm(0,0,0,$13,$14-1,$year-1900);
+ $date = Time::Local::timegm(0,0,0,$13,$14-1,$year);
}
#
# Honeywell HMR3000 PTNTHPR (Heading Pitch Roll) sentence (no date)
@@ -646,7 +646,7 @@ sub GetTime($)
{
my $timeStr = shift;
$timeStr =~ /^(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d+)(\.\d+)?(.*)/ or return undef;
- my $time = Time::Local::timegm($6,$5,$4,$3,$2-1,$1-1900);
+ my $time = Time::Local::timegm($6,$5,$4,$3,$2-1,$1);
$time += $7 if $7; # add fractional seconds
my $tz = $8;
# adjust for time zone (otherwise assume UTC)
@@ -815,7 +815,7 @@ sub SetGeoValues($$;$)
last;
}
if ($tz) {
- $time = Time::Local::timegm($sec,$min,$hr,$day,$mon-1,$year-1900);
+ $time = Time::Local::timegm($sec,$min,$hr,$day,$mon-1,$year);
# use timezone from date/time value
if ($tz ne 'Z') {
my $tzmin = $t1 * 60 + $t2;
Index: Image-ExifTool-10.55/lib/Image/ExifTool/Writer.pl
===================================================================
--- Image-ExifTool-10.55.orig/lib/Image/ExifTool/Writer.pl
+++ Image-ExifTool-10.55/lib/Image/ExifTool/Writer.pl
@@ -4376,7 +4376,7 @@ sub InverseDateTime($$;$$)
if (not $tz) {
if (eval { require Time::Local }) {
# determine timezone offset for this time
- my @args = ($a[4],$a[3],$a[2],$a[1],$a[0]-1,$yr-1900);
+ my @args = ($a[4],$a[3],$a[2],$a[1],$a[0]-1,$yr);
my $diff = Time::Local::timegm(@args) - TimeLocal(@args);
$tz = TimeZoneString($diff / 60);
} else {