Store the times internally in GMT. Do all manipulations in GMT. Then at the last moment, just as you're about to display results to the user, then convert to the user's local time.
I recommend using Date::Parse, but you'll have to augment its timezone offsets because it doesn't currently have Indochina Summer Time and Japan Daylight Time, for example.
#! /usr/bin/perl
use warnings;
use strict;
use Date::Format;
use Date::Parse;
# add timezone offsets
$Time::Zone::Zone{icst} = +7*3600;
$Time::Zone::Zone{jdt} = +9*3600;
while (<DATA>) {
chomp;
warn("$0: failed conversion for $_\n"), next
unless defined(my $time_t = str2time $_);
my @t = gmtime($time_t);
print $_, " => ", strftime("%Y-%m-%d %H:%M:%S", @t), "\n";
}
__DATA__
Sat Mar 06 09:00:00 ICST 2010
Fri Feb 19 19:30:00 JDT 2010
Fri Feb 19 19:30:00 PST 2010
Output:
Sat Mar 06 09:00:00 ICST 2010 => 2010-03-06 02:00:00
Fri Feb 19 19:30:00 JDT 2010 => 2010-02-19 10:30:00
Fri Feb 19 19:30:00 PST 2010 => 2010-02-20 03:30:00
To support the query you'd like, store the time in GMT plus an offset (i.e., from GMT to the local time from the API). Note that the code below assumes that if str2time
can parse a given time, strptime
can also. Change the loop to
my @dates;
while (<DATA>) {
chomp;
warn("$0: failed conversion for $_\n"), next
unless defined(my $time_t = str2time $_);
my $zone = (strptime $_)[-1];
my @t = gmtime($time_t);
push @dates => [ strftime("%Y-%m-%d %H:%M:%S", @t)
, sprintf("%+03d:%02d",
int($zone / 3600),
int($zone % 3600) / 60)
, $_
];
}
With the times collected, render it as SQL:
print "DROP TABLE IF EXISTS dates;\n",
"CREATE TABLE dates (date DATETIME, offset CHAR(6));\n",
"INSERT INTO dates (date,offset) VALUES\n",
join(",\n\n" =>
map(" -- $_->[2]\n" .
" ('$_->[0]','$_->[1]')", @dates)),
";\n",
"SELECT CONVERT_TZ(date,'+00:00',offset) FROM dates;\n"
The output is
DROP TABLE IF EXISTS dates;
CREATE TABLE dates (date DATETIME, offset CHAR(6));
INSERT INTO dates (date,offset) VALUES
-- Sat Mar 06 09:00:00 ICST 2010
('2010-03-06 02:00:00','+07:00'),
-- Fri Feb 19 19:30:00 JDT 2010
('2010-02-19 10:30:00','+09:00'),
-- Fri Feb 19 19:30:00 PST 2010
('2010-02-20 03:30:00','-08:00');
SELECT CONVERT_TZ(date,'+00:00',offset) FROM dates;
and we can pipe it to mysql
:
$ ./prog.pl | mysql -u username -D dbname
CONVERT_TZ(date,'+00:00',offset)
2010-03-06 09:00:00
2010-02-19 19:30:00
2010-02-19 19:30:00