diff options
author | Eric Wong (Contractor, The Linux Foundation) <e@80x24.org> | 2018-03-06 04:15:38 +0000 |
---|---|---|
committer | Eric Wong (Contractor, The Linux Foundation) <e@80x24.org> | 2018-03-06 04:51:41 +0000 |
commit | 35ac61764499c272d2760de2b2a432be412ecede (patch) | |
tree | 4902a8ce21a73c4e3f9b7724fcbadfd5e3038cf7 /lib/PublicInbox/MsgTime.pm | |
parent | 8515f32bd403cae734b2fed534a6708758d7949a (diff) | |
download | public-inbox-35ac61764499c272d2760de2b2a432be412ecede.tar.gz |
The first Received: header is believable since it typically hits the user's mail server and can be treated as relatively trustworthy. We still show the Date: in per-message (permalink) views, which may expose users for having incorrect Date: headers, but all the ISO YYYY-MM-DD dates we display will match what we see.
Diffstat (limited to 'lib/PublicInbox/MsgTime.pm')
-rw-r--r-- | lib/PublicInbox/MsgTime.pm | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/PublicInbox/MsgTime.pm b/lib/PublicInbox/MsgTime.pm new file mode 100644 index 00000000..87664f4b --- /dev/null +++ b/lib/PublicInbox/MsgTime.pm @@ -0,0 +1,51 @@ +# Copyright (C) 2018 all contributors <meta@public-inbox.org> +# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> +package PublicInbox::MsgTime; +use strict; +use warnings; +use base qw(Exporter); +our @EXPORT_OK = qw(msg_timestamp); +use Date::Parse qw(str2time); +use Time::Zone qw(tz_offset); + +sub msg_timestamp ($) { + my ($hdr) = @_; # Email::MIME::Header + my ($ts, $zone); + my $mid; + my @recvd = $hdr->header_raw('Received'); + 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; + $mid ||= $hdr->header_raw('Message-ID'); + warn "no date in $mid Received: $r\n"; + } + unless (defined $ts) { + my @date = $hdr->header_raw('Date'); + foreach my $d (@date) { + $zone = undef; + $ts = eval { str2time($d) }; + if ($@) { + $mid ||= $hdr->header_raw('Message-ID'); + warn "bad Date: $d in $mid: $@\n"; + } elsif ($d =~ /\s+([\+\-]\d+)\s*\z/) { + $zone = $1; + } + } + } + $ts = time unless defined $ts; + return $ts unless wantarray; + + $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'; + } + ($ts, $zone); +} + +1; |