package DateTime::Format::W3CDTF;
use strict;
use vars qw ($VERSION);
$VERSION = '0.04';
use DateTime;
sub new
{
my $class = shift;
return bless {}, $class;
}
# key is string length
my %valid_formats =
( 19 =>
{ params => [ qw( year month day hour minute second) ],
regex => qr/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)$/,
zero => {},
},
16 =>
{ params => [ qw( year month day hour minute) ],
regex => qr/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/,
zero => { second => 0 },
},
10 =>
{ params => [ qw( year month day ) ],
regex => qr/^(\d{4})-(\d\d)-(\d\d)$/,
zero => { hour => 0, minute => 0, second => 0 },
},
7 =>
{ params => [ qw( year month ) ],
regex => qr/^(\d{4})-(\d\d)$/,
zero => { day => 1, hour => 0, minute => 0, second => 0 },
},
4 =>
{ params => [ qw( year ) ],
regex => qr/^(\d\d\d\d)$/,
zero => { month => 1, day => 1, hour => 0, minute => 0, second => 0 }
}
);
sub parse_datetime
{
my ( $self, $date ) = @_;
# save for error messages
my $original = $date;
my %p;
if ( $date =~ s/([+-]\d\d:\d\d)$// )
{
$p{time_zone} = $1;
}
# Z at end means UTC
elsif ( $date =~ s/Z$// )
{
$p{time_zone} = 'UTC';
}
else
{
$p{time_zone} = 'floating';
}
my $format = $valid_formats{ length $date }
or die "Invalid W3CDTF datetime string ($original)";
@p{ @{ $format->{params} } } = $date =~ /$format->{regex}/;
return DateTime->new( %p, %{ $format->{zero} } );
}
sub format_datetime
{
my ( $self, $dt ) = @_;
# removed in 0.4 as it behaved improperly at midnight - kellan 2003/11/23
#my $base =
# ( $dt->hour || $dt->min || $dt->sec ?
# sprintf( '%04d-%02d-%02dT%02d:%02d:%02d',
# $dt->year, $dt->month, $dt->day,
# $dt->hour, $dt->minute, $dt->second ) :
# sprintf( '%04d-%02d-%02d', $dt->year, $dt->month, $dt->day )
# );
my $base = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d',
$dt->year, $dt->month, $dt->day,
$dt->hour, $dt->minute, $dt->second );
my $tz = $dt->time_zone;
return $base if $tz->is_floating;
return $base . 'Z' if $tz->is_utc;
=1= |