diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2012-03-30 12:07:25 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2012-03-30 12:07:25 +0000 |
commit | f1f9b3164e11c877ed5d509738551a56ac9b37f0 (patch) | |
tree | 8199aac0d7e7c5d5470173f422043044504d7c7b | |
download | HTTP-Date-tarball-master.tar.gz |
HTTP-Date-6.02HEADHTTP-Date-6.02master
-rw-r--r-- | Changes | 23 | ||||
-rw-r--r-- | MANIFEST | 7 | ||||
-rw-r--r-- | META.yml | 28 | ||||
-rw-r--r-- | Makefile.PL | 48 | ||||
-rw-r--r-- | README | 112 | ||||
-rw-r--r-- | lib/HTTP/Date.pm | 388 | ||||
-rwxr-xr-x | t/date.t | 180 |
7 files changed, 786 insertions, 0 deletions
@@ -0,0 +1,23 @@ +_______________________________________________________________________________ +2012-03-30 HTTP-Date 6.02 + +Added support for parsing dates with (faulty) double TZ spec [RT#75150] + +Doc tweaks. + + + +_______________________________________________________________________________ +2012-02-15 HTTP-Date 6.01 + +Restore perl-5.6 compatiblity. Drop MacOS (classic) support. + + + +_______________________________________________________________________________ +2011-02-25 HTTP-Date 6.00 + +Initial release of HTTP-Date as a separate distribution. There are no code +changes besides incrementing the version number since libwww-perl-5.837. + +The HTTP::Date module used to be bundled with the libwww-perl distribution. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..360176a --- /dev/null +++ b/MANIFEST @@ -0,0 +1,7 @@ +Changes +lib/HTTP/Date.pm +Makefile.PL +MANIFEST This list of files +README +t/date.t +META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..95e9697 --- /dev/null +++ b/META.yml @@ -0,0 +1,28 @@ +--- #YAML:1.0 +name: HTTP-Date +version: 6.02 +abstract: date conversion routines +author: + - Gisle Aas <gisle@activestate.com> +license: perl +distribution_type: module +configure_requires: + ExtUtils::MakeMaker: 0 +build_requires: + ExtUtils::MakeMaker: 0 +requires: + perl: 5.006002 + Time::Local: 0 +resources: + MailingList: mailto:libwww@perl.org + repository: http://github.com/gisle/http-date +no_index: + directory: + - t + - inc +generated_by: ExtUtils::MakeMaker version 6.57_05 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +recommends: + Time::Zone: 0 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..9279cb6 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,48 @@ +#!perl -w + +require 5.006002; +use strict; +use ExtUtils::MakeMaker; +WriteMakefile( + NAME => 'HTTP::Date', + VERSION_FROM => 'lib/HTTP/Date.pm', + ABSTRACT_FROM => 'lib/HTTP/Date.pm', + AUTHOR => 'Gisle Aas <gisle@activestate.com>', + LICENSE => "perl", + MIN_PERL_VERSION => 5.006002, + PREREQ_PM => { + 'Time::Local' => 0, + }, + META_MERGE => { + recommends => { + 'Time::Zone' => 0, + }, + resources => { + repository => 'http://github.com/gisle/http-date', + MailingList => 'mailto:libwww@perl.org', + } + }, +); + + +BEGIN { + # compatibility with older versions of MakeMaker + my $developer = -f ".gitignore"; + my %mm_req = ( + LICENCE => 6.31, + META_MERGE => 6.45, + META_ADD => 6.45, + MIN_PERL_VERSION => 6.48, + ); + undef(*WriteMakefile); + *WriteMakefile = sub { + my %arg = @_; + for (keys %mm_req) { + unless (eval { ExtUtils::MakeMaker->VERSION($mm_req{$_}) }) { + warn "$_ $@" if $developer; + delete $arg{$_}; + } + } + ExtUtils::MakeMaker::WriteMakefile(%arg); + }; +} @@ -0,0 +1,112 @@ +NAME + HTTP::Date - date conversion routines + +SYNOPSIS + use HTTP::Date; + + $string = time2str($time); # Format as GMT ASCII time + $time = str2time($string); # convert ASCII date to machine time + +DESCRIPTION + This module provides functions that deal the date formats used by the + HTTP protocol (and then some more). Only the first two functions, + time2str() and str2time(), are exported by default. + + time2str( [$time] ) + The time2str() function converts a machine time (seconds since + epoch) to a string. If the function is called without an argument or + with an undefined argument, it will use the current time. + + The string returned is in the format preferred for the HTTP + protocol. This is a fixed length subset of the format defined by RFC + 1123, represented in Universal Time (GMT). An example of a time + stamp in this format is: + + Sun, 06 Nov 1994 08:49:37 GMT + + str2time( $str [, $zone] ) + The str2time() function converts a string to machine time. It + returns `undef' if the format of $str is unrecognized, otherwise + whatever the `Time::Local' functions can make out of the parsed + time. Dates before the system's epoch may not work on all operating + systems. The time formats recognized are the same as for + parse_date(). + + The function also takes an optional second argument that specifies + the default time zone to use when converting the date. This + parameter is ignored if the zone is found in the date string itself. + If this parameter is missing, and the date string format does not + contain any zone specification, then the local time zone is assumed. + + If the zone is not "`GMT'" or numerical (like "`-0800'" or + "`+0100'"), then the `Time::Zone' module must be installed in order + to get the date recognized. + + parse_date( $str ) + This function will try to parse a date string, and then return it as + a list of numerical values followed by a (possible undefined) time + zone specifier; ($year, $month, $day, $hour, $min, $sec, $tz). The + $year returned will not have the number 1900 subtracted from it and + the $month numbers start with 1. + + In scalar context the numbers are interpolated in a string of the + "YYYY-MM-DD hh:mm:ss TZ"-format and returned. + + If the date is unrecognized, then the empty list is returned. + + The function is able to parse the following formats: + + "Wed, 09 Feb 1994 22:23:32 GMT" -- HTTP format + "Thu Feb 3 17:03:55 GMT 1994" -- ctime(3) format + "Thu Feb 3 00:00:00 1994", -- ANSI C asctime() format + "Tuesday, 08-Feb-94 14:15:29 GMT" -- old rfc850 HTTP format + "Tuesday, 08-Feb-1994 14:15:29 GMT" -- broken rfc850 HTTP format + + "03/Feb/1994:17:03:55 -0700" -- common logfile format + "09 Feb 1994 22:23:32 GMT" -- HTTP format (no weekday) + "08-Feb-94 14:15:29 GMT" -- rfc850 format (no weekday) + "08-Feb-1994 14:15:29 GMT" -- broken rfc850 format (no weekday) + + "1994-02-03 14:15:29 -0100" -- ISO 8601 format + "1994-02-03 14:15:29" -- zone is optional + "1994-02-03" -- only date + "1994-02-03T14:15:29" -- Use T as separator + "19940203T141529Z" -- ISO 8601 compact format + "19940203" -- only date + + "08-Feb-94" -- old rfc850 HTTP format (no weekday, no time) + "08-Feb-1994" -- broken rfc850 HTTP format (no weekday, no time) + "09 Feb 1994" -- proposed new HTTP format (no weekday, no time) + "03/Feb/1994" -- common logfile format (no time, no offset) + + "Feb 3 1994" -- Unix 'ls -l' format + "Feb 3 17:03" -- Unix 'ls -l' format + + "11-15-96 03:52PM" -- Windows 'dir' format + + The parser ignores leading and trailing whitespace. It also allow + the seconds to be missing and the month to be numerical in most + formats. + + If the year is missing, then we assume that the date is the first + matching date *before* current month. If the year is given with only + 2 digits, then parse_date() will select the century that makes the + year closest to the current date. + + time2iso( [$time] ) + Same as time2str(), but returns a "YYYY-MM-DD hh:mm:ss"-formatted + string representing time in the local time zone. + + time2isoz( [$time] ) + Same as time2str(), but returns a "YYYY-MM-DD hh:mm:ssZ"-formatted + string representing Universal Time. + +SEE ALSO + perlfunc, Time::Zone + +COPYRIGHT + Copyright 1995-1999, Gisle Aas + + This library is free software; you can redistribute it and/or modify it + under the same terms as Perl itself. + diff --git a/lib/HTTP/Date.pm b/lib/HTTP/Date.pm new file mode 100644 index 0000000..d05d216 --- /dev/null +++ b/lib/HTTP/Date.pm @@ -0,0 +1,388 @@ +package HTTP::Date; + +$VERSION = "6.02"; + +require Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(time2str str2time); +@EXPORT_OK = qw(parse_date time2iso time2isoz); + +use strict; +require Time::Local; + +use vars qw(@DoW @MoY %MoY); +@DoW = qw(Sun Mon Tue Wed Thu Fri Sat); +@MoY = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); +@MoY{@MoY} = (1..12); + +my %GMT_ZONE = (GMT => 1, UTC => 1, UT => 1, Z => 1); + + +sub time2str (;$) +{ + my $time = shift; + $time = time unless defined $time; + my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time); + sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT", + $DoW[$wday], + $mday, $MoY[$mon], $year+1900, + $hour, $min, $sec); +} + + +sub str2time ($;$) +{ + my $str = shift; + return undef unless defined $str; + + # fast exit for strictly conforming string + if ($str =~ /^[SMTWF][a-z][a-z], (\d\d) ([JFMAJSOND][a-z][a-z]) (\d\d\d\d) (\d\d):(\d\d):(\d\d) GMT$/) { + return eval { + my $t = Time::Local::timegm($6, $5, $4, $1, $MoY{$2}-1, $3); + $t < 0 ? undef : $t; + }; + } + + my @d = parse_date($str); + return undef unless @d; + $d[1]--; # month + + my $tz = pop(@d); + unless (defined $tz) { + unless (defined($tz = shift)) { + return eval { my $frac = $d[-1]; $frac -= ($d[-1] = int($frac)); + my $t = Time::Local::timelocal(reverse @d) + $frac; + $t < 0 ? undef : $t; + }; + } + } + + my $offset = 0; + if ($GMT_ZONE{uc $tz}) { + # offset already zero + } + elsif ($tz =~ /^([-+])?(\d\d?):?(\d\d)?$/) { + $offset = 3600 * $2; + $offset += 60 * $3 if $3; + $offset *= -1 if $1 && $1 eq '-'; + } + else { + eval { require Time::Zone } || return undef; + $offset = Time::Zone::tz_offset($tz); + return undef unless defined $offset; + } + + return eval { my $frac = $d[-1]; $frac -= ($d[-1] = int($frac)); + my $t = Time::Local::timegm(reverse @d) + $frac; + $t < 0 ? undef : $t - $offset; + }; +} + + +sub parse_date ($) +{ + local($_) = shift; + return unless defined; + + # More lax parsing below + s/^\s+//; # kill leading space + s/^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\s*//i; # Useless weekday + + my($day, $mon, $yr, $hr, $min, $sec, $tz, $ampm); + + # Then we are able to check for most of the formats with this regexp + (($day,$mon,$yr,$hr,$min,$sec,$tz) = + /^ + (\d\d?) # day + (?:\s+|[-\/]) + (\w+) # month + (?:\s+|[-\/]) + (\d+) # year + (?: + (?:\s+|:) # separator before clock + (\d\d?):(\d\d) # hour:min + (?::(\d\d))? # optional seconds + )? # optional clock + \s* + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + \s* + (?:\(\w+\)|\w{3,})? # ASCII representation of timezone. + \s*$ + /x) + + || + + # Try the ctime and asctime format + (($mon, $day, $hr, $min, $sec, $tz, $yr) = + /^ + (\w{1,3}) # month + \s+ + (\d\d?) # day + \s+ + (\d\d?):(\d\d) # hour:min + (?::(\d\d))? # optional seconds + \s+ + (?:([A-Za-z]+)\s+)? # optional timezone + (\d+) # year + \s*$ # allow trailing whitespace + /x) + + || + + # Then the Unix 'ls -l' date format + (($mon, $day, $yr, $hr, $min, $sec) = + /^ + (\w{3}) # month + \s+ + (\d\d?) # day + \s+ + (?: + (\d\d\d\d) | # year + (\d{1,2}):(\d{2}) # hour:min + (?::(\d\d))? # optional seconds + ) + \s*$ + /x) + + || + + # ISO 8601 format '1996-02-29 12:00:00 -0100' and variants + (($yr, $mon, $day, $hr, $min, $sec, $tz) = + /^ + (\d{4}) # year + [-\/]? + (\d\d?) # numerical month + [-\/]? + (\d\d?) # day + (?: + (?:\s+|[-:Tt]) # separator before clock + (\d\d?):?(\d\d) # hour:min + (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) + )? # optional clock + \s* + ([-+]?\d\d?:?(:?\d\d)? + |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) + \s*$ + /x) + + || + + # Windows 'dir' 11-12-96 03:52PM + (($mon, $day, $yr, $hr, $min, $ampm) = + /^ + (\d{2}) # numerical month + - + (\d{2}) # day + - + (\d{2}) # year + \s+ + (\d\d?):(\d\d)([APap][Mm]) # hour:min AM or PM + \s*$ + /x) + + || + return; # unrecognized format + + # Translate month name to number + $mon = $MoY{$mon} || + $MoY{"\u\L$mon"} || + ($mon =~ /^\d\d?$/ && $mon >= 1 && $mon <= 12 && int($mon)) || + return; + + # If the year is missing, we assume first date before the current, + # because of the formats we support such dates are mostly present + # on "ls -l" listings. + unless (defined $yr) { + my $cur_mon; + ($cur_mon, $yr) = (localtime)[4, 5]; + $yr += 1900; + $cur_mon++; + $yr-- if $mon > $cur_mon; + } + elsif (length($yr) < 3) { + # Find "obvious" year + my $cur_yr = (localtime)[5] + 1900; + my $m = $cur_yr % 100; + my $tmp = $yr; + $yr += $cur_yr - $m; + $m -= $tmp; + $yr += ($m > 0) ? 100 : -100 + if abs($m) > 50; + } + + # Make sure clock elements are defined + $hr = 0 unless defined($hr); + $min = 0 unless defined($min); + $sec = 0 unless defined($sec); + + # Compensate for AM/PM + if ($ampm) { + $ampm = uc $ampm; + $hr = 0 if $hr == 12 && $ampm eq 'AM'; + $hr += 12 if $ampm eq 'PM' && $hr != 12; + } + + return($yr, $mon, $day, $hr, $min, $sec, $tz) + if wantarray; + + if (defined $tz) { + $tz = "Z" if $tz =~ /^(GMT|UTC?|[-+]?0+)$/; + } + else { + $tz = ""; + } + return sprintf("%04d-%02d-%02d %02d:%02d:%02d%s", + $yr, $mon, $day, $hr, $min, $sec, $tz); +} + + +sub time2iso (;$) +{ + my $time = shift; + $time = time unless defined $time; + my($sec,$min,$hour,$mday,$mon,$year) = localtime($time); + sprintf("%04d-%02d-%02d %02d:%02d:%02d", + $year+1900, $mon+1, $mday, $hour, $min, $sec); +} + + +sub time2isoz (;$) +{ + my $time = shift; + $time = time unless defined $time; + my($sec,$min,$hour,$mday,$mon,$year) = gmtime($time); + sprintf("%04d-%02d-%02d %02d:%02d:%02dZ", + $year+1900, $mon+1, $mday, $hour, $min, $sec); +} + +1; + + +__END__ + +=head1 NAME + +HTTP::Date - date conversion routines + +=head1 SYNOPSIS + + use HTTP::Date; + + $string = time2str($time); # Format as GMT ASCII time + $time = str2time($string); # convert ASCII date to machine time + +=head1 DESCRIPTION + +This module provides functions that deal the date formats used by the +HTTP protocol (and then some more). Only the first two functions, +time2str() and str2time(), are exported by default. + +=over 4 + +=item time2str( [$time] ) + +The time2str() function converts a machine time (seconds since epoch) +to a string. If the function is called without an argument or with an +undefined argument, it will use the current time. + +The string returned is in the format preferred for the HTTP protocol. +This is a fixed length subset of the format defined by RFC 1123, +represented in Universal Time (GMT). An example of a time stamp +in this format is: + + Sun, 06 Nov 1994 08:49:37 GMT + +=item str2time( $str [, $zone] ) + +The str2time() function converts a string to machine time. It returns +C<undef> if the format of $str is unrecognized, otherwise whatever the +C<Time::Local> functions can make out of the parsed time. Dates +before the system's epoch may not work on all operating systems. The +time formats recognized are the same as for parse_date(). + +The function also takes an optional second argument that specifies the +default time zone to use when converting the date. This parameter is +ignored if the zone is found in the date string itself. If this +parameter is missing, and the date string format does not contain any +zone specification, then the local time zone is assumed. + +If the zone is not "C<GMT>" or numerical (like "C<-0800>" or +"C<+0100>"), then the C<Time::Zone> module must be installed in order +to get the date recognized. + +=item parse_date( $str ) + +This function will try to parse a date string, and then return it as a +list of numerical values followed by a (possible undefined) time zone +specifier; ($year, $month, $day, $hour, $min, $sec, $tz). The $year +will be the full 4-digit year, and $month numbers start with 1 (for January). + +In scalar context the numbers are interpolated in a string of the +"YYYY-MM-DD hh:mm:ss TZ"-format and returned. + +If the date is unrecognized, then the empty list is returned (C<undef> in +scalar context). + +The function is able to parse the following formats: + + "Wed, 09 Feb 1994 22:23:32 GMT" -- HTTP format + "Thu Feb 3 17:03:55 GMT 1994" -- ctime(3) format + "Thu Feb 3 00:00:00 1994", -- ANSI C asctime() format + "Tuesday, 08-Feb-94 14:15:29 GMT" -- old rfc850 HTTP format + "Tuesday, 08-Feb-1994 14:15:29 GMT" -- broken rfc850 HTTP format + + "03/Feb/1994:17:03:55 -0700" -- common logfile format + "09 Feb 1994 22:23:32 GMT" -- HTTP format (no weekday) + "08-Feb-94 14:15:29 GMT" -- rfc850 format (no weekday) + "08-Feb-1994 14:15:29 GMT" -- broken rfc850 format (no weekday) + + "1994-02-03 14:15:29 -0100" -- ISO 8601 format + "1994-02-03 14:15:29" -- zone is optional + "1994-02-03" -- only date + "1994-02-03T14:15:29" -- Use T as separator + "19940203T141529Z" -- ISO 8601 compact format + "19940203" -- only date + + "08-Feb-94" -- old rfc850 HTTP format (no weekday, no time) + "08-Feb-1994" -- broken rfc850 HTTP format (no weekday, no time) + "09 Feb 1994" -- proposed new HTTP format (no weekday, no time) + "03/Feb/1994" -- common logfile format (no time, no offset) + + "Feb 3 1994" -- Unix 'ls -l' format + "Feb 3 17:03" -- Unix 'ls -l' format + + "11-15-96 03:52PM" -- Windows 'dir' format + +The parser ignores leading and trailing whitespace. It also allow the +seconds to be missing and the month to be numerical in most formats. + +If the year is missing, then we assume that the date is the first +matching date I<before> current month. If the year is given with only +2 digits, then parse_date() will select the century that makes the +year closest to the current date. + +=item time2iso( [$time] ) + +Same as time2str(), but returns a "YYYY-MM-DD hh:mm:ss"-formatted +string representing time in the local time zone. + +=item time2isoz( [$time] ) + +Same as time2str(), but returns a "YYYY-MM-DD hh:mm:ssZ"-formatted +string representing Universal Time. + + +=back + +=head1 SEE ALSO + +L<perlfunc/time>, L<Time::Zone> + +=head1 COPYRIGHT + +Copyright 1995-1999, Gisle Aas + +This library is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=cut diff --git a/t/date.t b/t/date.t new file mode 100755 index 0000000..129904d --- /dev/null +++ b/t/date.t @@ -0,0 +1,180 @@ +#!perl -w + +use strict; +use Test; + +plan tests => 136; + +use HTTP::Date; + +# test str2time for supported dates. Test cases with 2 digit year +# will probably break in year 2044. +my(@tests) = +( + 'Thu Feb 3 00:00:00 GMT 1994', # ctime format + 'Thu Feb 3 00:00:00 1994', # same as ctime, except no TZ + + 'Thu, 03 Feb 1994 00:00:00 GMT', # proposed new HTTP format + 'Thursday, 03-Feb-94 00:00:00 GMT', # old rfc850 HTTP format + 'Thursday, 03-Feb-1994 00:00:00 GMT', # broken rfc850 HTTP format + + '03/Feb/1994:00:00:00 0000', # common logfile format + '03/Feb/1994:01:00:00 +0100', # common logfile format + '02/Feb/1994:23:00:00 -0100', # common logfile format + + '03 Feb 1994 00:00:00 GMT', # HTTP format (no weekday) + '03-Feb-94 00:00:00 GMT', # old rfc850 (no weekday) + '03-Feb-1994 00:00:00 GMT', # broken rfc850 (no weekday) + '03-Feb-1994 00:00 GMT', # broken rfc850 (no weekday, no seconds) + '03-Feb-1994 00:00', # VMS dir listing format + + '03-Feb-94', # old rfc850 HTTP format (no weekday, no time) + '03-Feb-1994', # broken rfc850 HTTP format (no weekday, no time) + '03 Feb 1994', # proposed new HTTP format (no weekday, no time) + '03/Feb/1994', # common logfile format (no time, no offset) + + #'Feb 3 00:00', # Unix 'ls -l' format (can't really test it here) + 'Feb 3 1994', # Unix 'ls -l' format + + "02-03-94 12:00AM", # Windows 'dir' format + + # ISO 8601 formats + '1994-02-03 00:00:00 +0000', + '1994-02-03', + '19940203', + '1994-02-03T00:00:00+0000', + '1994-02-02T23:00:00-0100', + '1994-02-02T23:00:00-01:00', + '1994-02-03T00:00:00 Z', + '19940203T000000Z', + '199402030000', + + # A few tests with extra space at various places + ' 03/Feb/1994 ', + ' 03 Feb 1994 0:00 ', + + # Tests a commonly used (faulty?) date format of php cms systems + 'Thu, 03 Feb 1994 00:00:00 +0000 GMT' +); + +my $time = 760233600; # assume broken POSIX counting of seconds +for (@tests) { + my $t; + if (/GMT/i) { + $t = str2time($_); + } + else { + $t = str2time($_, "GMT"); + } + my $t2 = str2time(lc($_), "GMT"); + my $t3 = str2time(uc($_), "GMT"); + + print "\n# '$_'\n"; + + ok($t, $time); + ok($t2, $time); + ok($t3, $time); +} + +# test time2str +ok(time2str($time), 'Thu, 03 Feb 1994 00:00:00 GMT'); + +# test the 'ls -l' format with missing year$ +# round to nearest minute 3 days ago. +$time = int((time - 3 * 24*60*60) /60)*60; +my ($min, $hr, $mday, $mon) = (localtime $time)[1,2,3,4]; +$mon = (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec))[$mon]; +my $str = sprintf("$mon %02d %02d:%02d", $mday, $hr, $min); +my $t = str2time($str); +ok($t, $time); + +# try some garbage. +for (undef, '', 'Garbage', + 'Mandag 16. September 1996', + '12 Arp 2003', +# 'Thu Feb 3 00:00:00 CET 1994', +# 'Thu, 03 Feb 1994 00:00:00 CET', +# 'Wednesday, 31-Dec-69 23:59:59 GMT', + + '1980-00-01', + '1980-13-01', + '1980-01-00', + '1980-01-32', + '1980-01-01 25:00:00', + '1980-01-01 00:61:00', + '1980-01-01 00:00:61', + ) +{ + my $bad = 0; + eval { + if (defined str2time $_) { + print "str2time($_) is not undefined\n"; + $bad++; + } + }; + print defined($_) ? "\n# '$_'\n" : "\n# undef\n"; + ok(!$@); + ok(!$bad); +} + +print "Testing AM/PM gruff...\n"; + +# Test the str2iso routines +use HTTP::Date qw(time2iso time2isoz); + +print "Testing time2iso functions\n"; + +$t = time2iso(str2time("11-12-96 0:00AM")); +ok($t, "1996-11-12 00:00:00"); + +$t = time2iso(str2time("11-12-96 12:00AM")); +ok($t, "1996-11-12 00:00:00"); + +$t = time2iso(str2time("11-12-96 0:00PM")); +ok($t, "1996-11-12 12:00:00"); + +$t = time2iso(str2time("11-12-96 12:00PM")); +ok($t, "1996-11-12 12:00:00"); + + +$t = time2iso(str2time("11-12-96 1:05AM")); +ok($t, "1996-11-12 01:05:00"); + +$t = time2iso(str2time("11-12-96 12:05AM")); +ok($t, "1996-11-12 00:05:00"); + +$t = time2iso(str2time("11-12-96 1:05PM")); +ok($t, "1996-11-12 13:05:00"); + +$t = time2iso(str2time("11-12-96 12:05PM")); +ok($t, "1996-11-12 12:05:00"); + +$t = str2time("2000-01-01 00:00:01.234"); +print "FRAC $t = ", time2iso($t), "\n"; +ok(abs(($t - int($t)) - 0.234) < 0.000001); + +$a = time2iso; +$b = time2iso(500000); +print "LOCAL $a $b\n"; +my $az = time2isoz; +my $bz = time2isoz(500000); +print "GMT $az $bz\n"; + +for ($a, $b) { ok(/^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d$/); } +for ($az, $bz) { ok(/^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$/); } + +# Test the parse_date interface +use HTTP::Date qw(parse_date); + +my @d = parse_date("Jan 1 2001"); + +ok(!defined(pop(@d))); +ok("@d", "2001 1 1 0 0 0"); + +# This test will break around year 2070 +ok(parse_date("03-Feb-20"), "2020-02-03 00:00:00"); + +# This test will break around year 2048 +ok(parse_date("03-Feb-98"), "1998-02-03 00:00:00"); + +print "HTTP::Date $HTTP::Date::VERSION\n"; |