On Fri, May 14, 2021 at 09:43:21PM -0400, John Hawkinson <jh...@alum.mit.edu> wrote:
> For what it's worth, I have a desire for the opposite kind of feature, > although I don't quite know how it should work. > I want to see and use timezones as displayed in messages as long as > they are nearby US timezones that my brain is facile with the trivial > arithmetic for (i.e. US/Eastern, US/Central, US/Pacific, and I suppose > the rare US/Mountain). > > But when a header comes in UTC, I'd much rather convert it to local > time, especially so I don't have to think about how DST affects the > offset. > [...] > -- > jh...@alum.mit.edu > John Hawkinson When my workplace switched to office365 (all but me anyway), their emails started arriving with UTC date headers. So I wrote a procmail recipe to filter incoming emails through a little perl script to convert the date header to my timezone. it's attached. the local timezone is hardcoded (sorry) but can be changed as needed. cheers, raf
#!/usr/bin/env perl use warnings; use strict; # procmail_filter_fix_outlook_date_header.pl # # This is an email filter to be run by procmail as email arrives. # It replaces UTC Date: headers in incoming email with the local timezone. # Outlook/Exchange refuses to use the sender's local timezone in Date: headers. # This can't recover the lost information about the true timezone of the # sender, but at least you won't need to perform timezone calculations in # your head when reading emails from your own work colleagues. # # usage (in ~/.procmailrc): # # :0 fw # * ^From:.*@(domain_that_uses_exchange\.com|and_another\.com) # | procmail_filter_fix_outlook_date_header.pl # # WARNING: This is hard-coded to convert UTC to Australia/Sydney # and needs to be modified if you are in a different timezone. # # 20200205 raf <r...@raf.org> # Update these suit your local timezone. my $local_tz = 'Australia/Sydney'; # Or `cat /etc/timezone` if present ($TZ didn't work for me) my @local_offsets_by_dst = ('+1000', '+1100'); # How to get these programmatically? use POSIX; my %month_name2num = (Jan => 0, Feb => 1, Mar => 2, Apr => 3, May => 4, Jun => 5, Jul => 6, Aug => 7, Sep => 8, Oct => 9, Nov => 10, Dec => 11); my %month_num2name = (0 => 'Jan', 1 => 'Feb', 2 => 'Mar', 3 => 'Apr', 4 => 'May', 5 => 'Jun', 6 => 'Jul', 7 => 'Aug', 8 => 'Sep', 9 => 'Oct', 10 => 'Nov', 11 => 'Dec'); my %day_num2name = (0 => 'Sun', 1 => 'Mon', 2 => 'Tue', 3 => 'Wed', 4 => 'Thu', 5 => 'Fri', 6 => 'Sat'); while (<>) { # Date: Tue, 4 Feb 2020 22:41:34 +0000 my ($day, $month, $year, $hour, $minute, $second, $eol) = /^Date: (?:Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+(\d{1,2})\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{4})\s+(\d{1,2}):(\d{2}):(\d{2}) \+0000(?:\s+\([A-Z]+\))?(\s*)$/; if (defined $day && defined $month && defined $year && defined $hour && defined $minute && defined $second) { print('X-Original-' . $_); local($ENV{TZ}) = 'UTC'; my $t = mktime $second, $minute, $hour, $day, $month_name2num{$month}, $year - 1900; $ENV{TZ} = $local_tz; my ($sec, $min, $hr, $d, $m, $y, $wday, $yday, $isdst) = localtime($t); $_ = sprintf('Date: %s, %d %s %d %02d:%02d:%02d %s%s', $day_num2name{$wday}, $d, $month_num2name{$m}, @{[$y + 1900]}, $hr, $min, $sec, $local_offsets_by_dst[$isdst], $eol); } print; } # vi:set ts=4 sw=4: