there doesn't seem to be a module that takes datetimes as described by ISO
8601 (http://www.cl.cam.ac.uk/~mgk25/iso-time.html) and converts them to a
unix timestamp. several other modules came close, but are missing a few
things.
this module will provide a single function ToUnixTime
(suggestions welcome on a better name) that converts datetimes like:
19951231T235959
2001-10-11T11:43:00,0
2002-07-14T22:34:59+00:00
into unix timestamps.
if a time offset is not present in the string, UTC is used. a different
default timezone may be passed in as an argument like so:
DateTime::ISO::ToUnixTime($datetime, zone=>'EST5EDT')
comments?
thanks
code follows below if you're interested in implementation:
sub ToUnixTime ($@)
{
my $date = shift || return;
my %args = @_;
my $zone = delete $args{zone} || 'UTC';
my @match = $date =~ m
{
^
(\d\d\d\d) # $1 = YYYY
-?
(\d\d) # $2 = MM
-?
(\d\d) # $3 = DD
[ T]
(\d\d) # $4 = hh
(?:
:?
(\d\d) # $5 = mm
(?:
:?
(\d\d) # $6 = ss
(?:[.,]\d+)? # fractions of seconds
)?
)?
(?:
([+-]?\d\d) # $7 = timezone hh
(?:
:?
(\d\d) # $8 = timezone mm
)?
|
Z
)?
$
}x;
unless (@match)
{
$@ = 'unknow date format';
return;
}
my ($YYYY, $MM, $DD, $hh, $mm, $ss, $zhh, $zmm) = @match;
$mm ||= 0;
$ss ||= 0;
require Time::Local;
## Time::Local croaks on bad values.
my $time = eval {
local $ENV{TZ} = $zone;
Time::Local::timelocal($ss, $mm, $hh, $DD, $MM-1, $YYYY-1900);
};
return if $@;
delete $ENV{TZ} unless $ENV{TZ}; ## local()izing leaves a "ghost" value.
## Adjust for tz offset.
$time -= $zhh * 60 * 60 if $zhh;
$time -= $zmm * 60 if $zmm;
return $time;
}