X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FMsgTime.pm;h=f3ebb6447a9cfe341b381beb9f19671b01caf331;hb=ae80a3fdb53d70142624f2691ed8ed84eddda66b;hp=c67a41fff2effa6b2bfbc163040936350f5a4d8c;hpb=9c9170688649c975d866b5326b12623dc8f4604b;p=public-inbox.git diff --git a/lib/PublicInbox/MsgTime.pm b/lib/PublicInbox/MsgTime.pm index c67a41ff..f3ebb644 100644 --- a/lib/PublicInbox/MsgTime.pm +++ b/lib/PublicInbox/MsgTime.pm @@ -5,19 +5,31 @@ use strict; use warnings; use base qw(Exporter); our @EXPORT_OK = qw(msg_timestamp msg_datestamp); -use Date::Parse qw(str2time); -use Time::Zone qw(tz_offset); +use Date::Parse qw(str2time strptime); + +sub str2date_zone ($) { + my ($date) = @_; + + my $ts = str2time($date); + return undef unless(defined $ts); + + # off is the time zone offset in seconds from GMT + my ($ss,$mm,$hh,$day,$month,$year,$off) = strptime($date); + return undef unless(defined $off); + + # Compute the time zone from offset + my $sign = ($off < 0) ? '-' : '+'; + my $hour = abs(int($off / 3600)); + my $min = ($off / 60) % 60; + my $zone = sprintf('%s%02d%02d', $sign, $hour, $min); -sub zone_clamp ($) { - my ($zone) = @_; - $zone ||= '+0000'; # "-1200" is the furthest westermost zone offset, # but git fast-import is liberal so we use "-1400" if ($zone >= 1400 || $zone <= -1400) { warn "bogus TZ offset: $zone, ignoring and assuming +0000\n"; $zone = '+0000'; } - $zone; + [$ts, $zone]; } sub time_response ($) { @@ -28,37 +40,32 @@ sub time_response ($) { sub msg_received_at ($) { my ($hdr) = @_; # Email::MIME::Header my @recvd = $hdr->header_raw('Received'); - my ($ts, $zone); + my ($ts); foreach my $r (@recvd) { - $zone = undef; $r =~ /\s*(\d+\s+[[:alpha:]]+\s+\d{2,4}\s+ \d+\D\d+(?:\D\d+)\s+([\+\-]\d+))/sx or next; - $zone = $2; - $ts = eval { str2time($1) } and last; + $ts = eval { str2date_zone($1) } and return $ts; my $mid = $hdr->header_raw('Message-ID'); warn "no date in $mid Received: $r\n"; } - defined $ts ? [ $ts, zone_clamp($zone) ] : undef; + undef; } sub msg_date_only ($) { my ($hdr) = @_; # Email::MIME::Header my @date = $hdr->header_raw('Date'); - my ($ts, $zone); + my ($ts); foreach my $d (@date) { - $zone = undef; # Y2K problems: 3-digit years $d =~ s!([A-Za-z]{3}) (\d{3}) (\d\d:\d\d:\d\d)! my $yyyy = $2 + 1900; "$1 $yyyy $3"!e; - $ts = eval { str2time($d) }; + $ts = eval { str2date_zone($d) } and return $ts; if ($@) { my $mid = $hdr->header_raw('Message-ID'); warn "bad Date: $d in $mid: $@\n"; - } elsif ($d =~ /\s+([\+\-]\d+)\s*\z/) { - $zone = $1; } } - defined $ts ? [ $ts, zone_clamp($zone) ] : undef; + undef; } # Favors Received header for sorting globally