Update Time-Piece to CPAN version 1.30
authorChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Wed, 3 Jun 2015 15:06:58 +0000 (16:06 +0100)
committerChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Wed, 3 Jun 2015 15:06:58 +0000 (16:06 +0100)
  [DELTA]

1.30    2015-05-16
        - Stable release. Overview from 1.29:
        - Make strftime more portable + fix %z %z
        - Add many more tests
        - Clean inheritance

1.29_05   2015-05-02
        - Combine multiple 'use constant' statements (saves 0.5ms at runtime)
        - Don't leave c_epoch undef
        - deprecate parse() function
        - More constructor tests
        - export() calls Exporter::export

1.29_04   2015-04-09
        - Clean inheritance of Exporter and DynaLoader (Thanks dolmen!)
        - Refactor _strftime to use localtime/gmtime to generate tm struct

1.29_03   2015-04-04
        - Don't mix gmtime and mktime in _strftime
        - Clean whitespace at end of lines
        - Add more tests for DST issues and also strptime parsing

1.29_02   2015-04-04
        - Fix handling of %Z and %z in strftime (hopefully)
        - Remove compile warnings for int cast

1.29_01   2015-03-30
        - Fix handling of %Z and %z in strftime (in progress)
        - Remove unused constants from Time::Seconds (Thanks Xaerxess!)
        - _strftime: use system mktime to better support past/future dates
        - Relicense strptime as BSD 2-clause http://git.io/vfNSg

MANIFEST
Porting/Maintainers.pl
cpan/Time-Piece/Piece.pm
cpan/Time-Piece/Piece.xs
cpan/Time-Piece/Seconds.pm
cpan/Time-Piece/t/01base.t
cpan/Time-Piece/t/02core.t
cpan/Time-Piece/t/02core_dst.t [new file with mode: 0644]
cpan/Time-Piece/t/06subclass.t
cpan/Time-Piece/t/lib/Time/Piece/Twin.pm [new file with mode: 0644]

index 289e9f2..90fb749 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2550,12 +2550,14 @@ cpan/Time-Piece/Piece.pm        Time::Piece extension
 cpan/Time-Piece/Piece.xs       Time::Piece extension
 cpan/Time-Piece/Seconds.pm     Time::Piece extension
 cpan/Time-Piece/t/01base.t     Test for Time::Piece
+cpan/Time-Piece/t/02core_dst.t
 cpan/Time-Piece/t/02core.t     Test for Time::Piece
 cpan/Time-Piece/t/03compare.t  Test for Time::Piece
 cpan/Time-Piece/t/04mjd.t      Test for Time::Piece
 cpan/Time-Piece/t/05overload.t Test for Time::Piece
 cpan/Time-Piece/t/06subclass.t Test for Time::Piece
 cpan/Time-Piece/t/07arith.t    Test for Time::Piece
+cpan/Time-Piece/t/lib/Time/Piece/Twin.pm
 cpan/Unicode-Collate/Collate/allkeys.txt       Unicode::Collate
 cpan/Unicode-Collate/Collate/CJK/Big5.pm                       Unicode::Collate
 cpan/Unicode-Collate/Collate/CJK/GB2312.pm                     Unicode::Collate
index 2fc719f..0f573d1 100755 (executable)
@@ -1210,7 +1210,7 @@ use File::Glob qw(:case);
     },
 
     'Time::Piece' => {
-        'DISTRIBUTION' => 'RJBS/Time-Piece-1.29.tar.gz',
+        'DISTRIBUTION' => 'RJBS/Time-Piece-1.30.tar.gz',
         'FILES'        => q[cpan/Time-Piece],
     },
 
index aaf63ee..a8b80fc 100644 (file)
@@ -2,13 +2,11 @@ package Time::Piece;
 
 use strict;
 
-require Exporter;
-require DynaLoader;
 use Time::Seconds;
 use Carp;
 use Time::Local;
 
-our @ISA = qw(Exporter DynaLoader);
+use Exporter ();
 
 our @EXPORT = qw(
     localtime
@@ -19,9 +17,13 @@ our %EXPORT_TAGS = (
     ':override' => 'internal',
     );
 
-our $VERSION = '1.29';
+our $VERSION = '1.30';
 
-bootstrap Time::Piece $VERSION;
+require DynaLoader;
+{
+    local *dl_load_flags = \&DynaLoader::dl_load_flags;
+    __PACKAGE__->DynaLoader::bootstrap($VERSION);
+}
 
 my $DATE_SEP = '-';
 my $TIME_SEP = ':';
@@ -31,17 +33,19 @@ my @FULLMON_LIST = qw(January February March April May June July
 my @DAY_LIST = qw(Sun Mon Tue Wed Thu Fri Sat);
 my @FULLDAY_LIST = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
 
-use constant 'c_sec' => 0;
-use constant 'c_min' => 1;
-use constant 'c_hour' => 2;
-use constant 'c_mday' => 3;
-use constant 'c_mon' => 4;
-use constant 'c_year' => 5;
-use constant 'c_wday' => 6;
-use constant 'c_yday' => 7;
-use constant 'c_isdst' => 8;
-use constant 'c_epoch' => 9;
-use constant 'c_islocal' => 10;
+use constant {
+    'c_sec' => 0,
+    'c_min' => 1,
+    'c_hour' => 2,
+    'c_mday' => 3,
+    'c_mon' => 4,
+    'c_year' => 5,
+    'c_wday' => 6,
+    'c_yday' => 7,
+    'c_isdst' => 8,
+    'c_epoch' => 9,
+    'c_islocal' => 10,
+};
 
 sub localtime {
     unshift @_, __PACKAGE__ unless eval { $_[0]->isa('Time::Piece') };
@@ -62,9 +66,9 @@ sub gmtime {
 sub new {
     my $class = shift;
     my ($time) = @_;
-    
+
     my $self;
-    
+
     if (defined($time)) {
         $self = $class->localtime($time);
     }
@@ -74,7 +78,7 @@ sub new {
     else {
         $self = $class->localtime();
     }
-    
+
     return bless $self, ref($class) || $class;
 }
 
@@ -82,6 +86,10 @@ sub parse {
     my $proto = shift;
     my $class = ref($proto) || $proto;
     my @components;
+
+    warnings::warnif("deprecated", 
+        "parse() is deprecated, use strptime() instead.");
+
     if (@_ > 1) {
         @components = @_;
     }
@@ -89,7 +97,7 @@ sub parse {
         @components = shift =~ /(\d+)$DATE_SEP(\d+)$DATE_SEP(\d+)(?:(?:T|\s+)(\d+)$TIME_SEP(\d+)(?:$TIME_SEP(\d+)))/;
         @components = reverse(@components[0..5]);
     }
-    return $class->new(_strftime("%s", @components));
+    return $class->new(_strftime("%s", timelocal(@components)));
 }
 
 sub _mktime {
@@ -98,7 +106,9 @@ sub _mktime {
            ? ref $class
            : $class;
     if (ref($time)) {
-        $time->[c_epoch] = undef;
+        my @tm_parts = (@{$time}[c_sec .. c_mon], $time->[c_year]+1900);
+        $time->[c_epoch] = $islocal ? timelocal(@tm_parts) : timegm(@tm_parts);
+
         return wantarray ? @$time : bless [@$time[0..9], $islocal], $class;
     }
     _tzset();
@@ -122,13 +132,13 @@ sub export {
       no warnings 'redefine';
       *{$to . "::$method"} = $_special_exports{$method}->($class);
     } else {
-      $class->SUPER::export($to, $method);
+      $class->Exporter::export($to, $method);
     }
   }
 }
 
 sub import {
-    # replace CORE::GLOBAL localtime and gmtime if required
+    # replace CORE::GLOBAL localtime and gmtime if passed :override
     my $class = shift;
     my %params;
     map($params{$_}++,@_,@EXPORT);
@@ -136,7 +146,7 @@ sub import {
         $class->export('CORE::GLOBAL', keys %params);
     }
     else {
-        $class->export((caller)[0], keys %params);
+        $class->export(scalar caller, keys %params);
     }
 }
 
@@ -279,7 +289,7 @@ sub isdst {
 # Thanks to Tony Olekshy <olekshy@cs.ualberta.ca> for this algorithm
 sub tzoffset {
     my $time = shift;
-    
+
     return Time::Seconds->new(0) unless $time->[c_islocal];
 
     my $epoch = $time->epoch;
@@ -447,19 +457,22 @@ sub month_last_day {
     return $MON_LAST[$_mon] + ($_mon == 1 ? _is_leap_year($year) : 0);
 }
 
+#since %z and %Z are not portable lets just
+#parse it out before calling native strftime
+#(but only if we are in UTC time)
+my %GMT_REPR = (
+    '%z' => '+0000',
+    '%Z' => 'UTC',
+);
+
 sub strftime {
     my $time = shift;
-    my $tzname = $time->[c_islocal] ? '%Z' : 'UTC';
-    my $format = @_ ? shift(@_) : "%a, %d %b %Y %H:%M:%S $tzname";
-    if (!defined $time->[c_wday]) {
-        if ($time->[c_islocal]) {
-            return _strftime($format, CORE::localtime($time->epoch));
-        }
-        else {
-            return _strftime($format, CORE::gmtime($time->epoch));
-        }
+    my $format = @_ ? shift(@_) : '%a, %d %b %Y %H:%M:%S %Z';
+    if (! $time->[c_islocal]) {
+        $format =~ s/(%.)/$GMT_REPR{$1} || $1/eg;
     }
-    return _strftime($format, (@$time)[c_sec..c_isdst]);
+
+    return _strftime($format, $time->epoch, $time->[c_islocal]);
 }
 
 sub strptime {
@@ -550,7 +563,7 @@ sub subtract {
        # to override this function.
        return $rhs - "$time";
     }
-    
+
     if (UNIVERSAL::isa($rhs, 'Time::Piece')) {
         return Time::Seconds->new($time->epoch - $rhs->epoch);
     }
@@ -592,9 +605,9 @@ sub compare {
 
 sub add_months {
     my ($time, $num_months) = @_;
-    
+
     croak("add_months requires a number of months") unless defined($num_months);
-    
+
     my $final_month = $time->_mon + $num_months;
     my $num_years = 0;
     if ($final_month > 11 || $final_month < 0) {
@@ -607,10 +620,10 @@ sub add_months {
             $num_years = int($final_month / 12);
         }
         $num_years-- if ($final_month < 0);
-        
+
         $final_month = $final_month % 12;
     }
-    
+
     my @vals = _mini_mktime($time->sec, $time->min, $time->hour,
                             $time->mday, $final_month, $time->year - 1900 + $num_years);
     # warn(sprintf("got %d vals: %d-%d-%d %d:%d:%d [%d]\n", scalar(@vals), reverse(@vals), $time->[c_islocal]));
index 0798b34..eafb790 100644 (file)
@@ -67,7 +67,7 @@ my_init_tm(struct tm *ptm)        /* see mktime, strftime and asctime    */
 #else
 /* use core version from util.c in 5.8.0 and later */
 # define my_init_tm init_tm
-#endif 
+#endif
 
 #ifdef WIN32
 
@@ -312,6 +312,7 @@ my_mini_mktime(struct tm *ptm)
 #       define strncasecmp(x,y,n) strnicmp(x,y,n)
 #   endif
 
+/* strptime.c    0.1 (Powerdog) 94/03/27 */
 /* strptime copied from freebsd with the following copyright: */
 /*
  * Copyright (c) 1994 Powerdog Industries.  All rights reserved.
@@ -319,18 +320,14 @@ my_mini_mktime(struct tm *ptm)
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
+ *
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
+ *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer
  *    in the documentation and/or other materials provided with the
  *    distribution.
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgement:
- *      This product includes software developed by Powerdog Industries.
- * 4. The name of Powerdog Industries may not be used to endorse or
- *    promote products derived from this software without specific prior
- *    written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -343,15 +340,11 @@ my_mini_mktime(struct tm *ptm)
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Powerdog Industries.
  */
-#ifndef lint
-#ifndef NOID
-static char copyright[] =
-"@(#) Copyright (c) 1994 Powerdog Industries.  All rights reserved.";
-static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27";
-#endif /* !defined NOID */
-#endif /* not lint */
 
 #include <time.h>
 #include <ctype.h>
@@ -366,7 +359,7 @@ struct lc_time_T {
     const char *    month[12];
     const char *    wday[7];
     const char *    weekday[7];
-    const char *    X_fmt;     
+    const char *    X_fmt;
     const char *    x_fmt;
     const char *    c_fmt;
     const char *    am;
@@ -685,7 +678,7 @@ label:
 
                case 'A':
                case 'a':
-                       for (i = 0; i < asizeof(Locale->weekday); i++) {
+                       for (i = 0; i < (int)asizeof(Locale->weekday); i++) {
                                if (c == 'A') {
                                        len = strlen(Locale->weekday[i]);
                                        if (strncasecmp(buf,
@@ -700,7 +693,7 @@ label:
                                                break;
                                }
                        }
-                       if (i == asizeof(Locale->weekday))
+                       if (i == (int)asizeof(Locale->weekday))
                                return 0;
 
                        tm->tm_wday = i;
@@ -779,7 +772,7 @@ label:
                case 'B':
                case 'b':
                case 'h':
-                       for (i = 0; i < asizeof(Locale->month); i++) {
+                       for (i = 0; i < (int)asizeof(Locale->month); i++) {
                                if (Oalternative) {
                                        if (c == 'B') {
                                                len = strlen(Locale->alt_month[i]);
@@ -804,7 +797,7 @@ label:
                                        }
                                }
                        }
-                       if (i == asizeof(Locale->month))
+                       if (i == (int)asizeof(Locale->month))
                                return 0;
 
                        tm->tm_mon = i;
@@ -896,7 +889,7 @@ label:
                        const char *cp;
                        char *zonestr;
 
-                       for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) 
+                       for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp)
                             {/*empty*/}
                        if (cp - buf) {
                                zonestr = (char *)malloc(cp - buf + 1);
@@ -970,6 +963,7 @@ push_common_tm(pTHX_ SV ** SP, struct tm *mytm)
        PUSHs(newSViv(mytm->tm_year));
        PUSHs(newSViv(mytm->tm_wday));
        PUSHs(newSViv(mytm->tm_yday));
+       PUSHs(newSViv(mytm->tm_isdst));
        return SP;
 }
 
@@ -986,11 +980,8 @@ return_11part_tm(pTHX_ SV ** SP, struct tm *mytm)
        my_mini_mktime(mytm);
 
   /* warn("tm: %d-%d-%d %d:%d:%d\n", mytm.tm_year, mytm.tm_mon, mytm.tm_mday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec); */
-
        EXTEND(SP, 11);
        SP = push_common_tm(aTHX_ SP, mytm);
-       /* isdst */
-       PUSHs(newSViv(0));
        /* epoch */
        PUSHs(newSViv(0));
        /* islocal */
@@ -1013,37 +1004,24 @@ MODULE = Time::Piece     PACKAGE = Time::Piece
 PROTOTYPES: ENABLE
 
 void
-_strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
-    char *        fmt
-    int        sec
-    int        min
-    int        hour
-    int        mday
-    int        mon
-    int        year
-    int        wday
-    int        yday
-    int        isdst
+_strftime(fmt, epoch, islocal = 1)
+    char *      fmt
+    time_t      epoch
+    int         islocal
     CODE:
     {
         char tmpbuf[128];
         struct tm mytm;
         int len;
-        memset(&mytm, 0, sizeof(mytm));
-        my_init_tm(&mytm);    /* XXX workaround - see my_init_tm() above */
-        mytm.tm_sec = sec;
-        mytm.tm_min = min;
-        mytm.tm_hour = hour;
-        mytm.tm_mday = mday;
-        mytm.tm_mon = mon;
-        mytm.tm_year = year;
-        mytm.tm_wday = wday;
-        mytm.tm_yday = yday;
-        mytm.tm_isdst = isdst;
-        my_mini_mktime(&mytm);
+
+        if(islocal == 1)
+            mytm = *localtime(&epoch);
+        else
+            mytm = *gmtime(&epoch);
+
         len = strftime(tmpbuf, sizeof tmpbuf, fmt, &mytm);
         /*
-        ** The following is needed to handle to the situation where 
+        ** The following is needed to handle to the situation where
         ** tmpbuf overflows.  Basically we want to allocate a buffer
         ** and try repeatedly.  The reason why it is so complicated
         ** is that getting a return value of 0 from strftime can indicate
@@ -1107,6 +1085,7 @@ _strptime ( string, format )
   PPCODE:
        t = 0;
        mytm = *gmtime(&t);
+       mytm.tm_isdst = -1; /* -1 means we don't know */
        got_GMT = 0;
 
        remainder = (char *)_strptime(aTHX_ string, format, &mytm, &got_GMT);
@@ -1149,7 +1128,7 @@ _crt_localtime(time_t sec)
         if(ix) mytm = *gmtime(&sec);
         else mytm = *localtime(&sec);
         /* Need to get: $s,$n,$h,$d,$m,$y */
-        
+
         EXTEND(SP, 9);
         SP = push_common_tm(aTHX_ SP, &mytm);
         PUSHs(newSViv(mytm.tm_isdst));
index 8e5b52b..fb5d441 100644 (file)
@@ -1,53 +1,49 @@
 package Time::Seconds;
 use strict;
-use vars qw/@EXPORT @EXPORT_OK/;
 
-our $VERSION = '1.29';
+our $VERSION = '1.30';
 
 use Exporter 5.57 'import';
 
-@EXPORT = qw(
-    ONE_MINUTE 
-    ONE_HOUR 
-    ONE_DAY 
-    ONE_WEEK 
+our @EXPORT = qw(
+    ONE_MINUTE
+    ONE_HOUR
+    ONE_DAY
+    ONE_WEEK
     ONE_MONTH
-    ONE_REAL_MONTH
     ONE_YEAR
-    ONE_REAL_YEAR
     ONE_FINANCIAL_MONTH
-    LEAP_YEAR 
+    LEAP_YEAR
     NON_LEAP_YEAR
 );
 
-@EXPORT_OK = qw(cs_sec cs_mon);
-
-use constant ONE_MINUTE => 60;
-use constant ONE_HOUR => 3_600;
-use constant ONE_DAY => 86_400;
-use constant ONE_WEEK => 604_800;
-use constant ONE_MONTH => 2_629_744; # ONE_YEAR / 12
-use constant ONE_REAL_MONTH => '1M';
-use constant ONE_YEAR => 31_556_930; # 365.24225 days
-use constant ONE_REAL_YEAR  => '1Y';
-use constant ONE_FINANCIAL_MONTH => 2_592_000; # 30 days
-use constant LEAP_YEAR => 31_622_400; # 366 * ONE_DAY
-use constant NON_LEAP_YEAR => 31_536_000; # 365 * ONE_DAY
-
-# hacks to make Time::Piece compile once again
-use constant cs_sec => 0;
-use constant cs_mon => 1;
-
-use overload 
-                'fallback' => 'undef',
-                '0+' => \&seconds,
-                '""' => \&seconds,
-                '<=>' => \&compare,
-                '+' => \&add,
-                '-' => \&subtract,
-                '-=' => \&subtract_from,
-                '+=' => \&add_to,
-                '=' => \&copy;
+our @EXPORT_OK = qw(cs_sec cs_mon);
+
+use constant {
+    ONE_MINUTE => 60,
+    ONE_HOUR => 3_600,
+    ONE_DAY => 86_400,
+    ONE_WEEK => 604_800,
+    ONE_MONTH => 2_629_744, # ONE_YEAR / 12
+    ONE_YEAR => 31_556_930, # 365.24225 days
+    ONE_FINANCIAL_MONTH => 2_592_000, # 30 days
+    LEAP_YEAR => 31_622_400, # 366 * ONE_DAY
+    NON_LEAP_YEAR => 31_536_000, # 365 * ONE_DAY
+    # hacks to make Time::Piece compile once again
+    cs_sec => 0,
+    cs_mon => 1,
+};
+
+use overload
+    'fallback' => 'undef',
+    '0+' => \&seconds,
+    '""' => \&seconds,
+    '<=>' => \&compare,
+    '+' => \&add,
+    '-' => \&subtract,
+    '-=' => \&subtract_from,
+    '+=' => \&add_to,
+    '=' => \&copy;
 
 sub new {
     my $class = shift;
@@ -229,8 +225,8 @@ The following methods are available:
     $val->hours;
     $val->days;
     $val->weeks;
-       $val->months;
-       $val->financial_months; # 30 days
+    $val->months;
+    $val->financial_months; # 30 days
     $val->years;
     $val->pretty; # gives English representation of the delta
 
index 530cd3d..fb2045e 100644 (file)
@@ -1,4 +1,4 @@
-use Test::More tests => 7;
+use Test::More tests => 13;
 
 BEGIN { use_ok('Time::Piece'); }
 
@@ -17,3 +17,23 @@ isa_ok($g, 'Time::Piece', 'current gmtime');
 
 my $l = localtime;
 isa_ok($l, 'Time::Piece', 'current localtime');
+
+#without export
+$g = Time::Piece::gmtime;
+isa_ok($g, 'Time::Piece', 'fully qualified gmtime');
+
+$l = Time::Piece::localtime;
+isa_ok($l, 'Time::Piece', 'full qualified localtime');
+
+#via new
+$l = Time::Piece->new(315532800);
+isa_ok($l, 'Time::Piece', 'custom localtime via new');
+
+#via new again
+$l = $l->new();
+isa_ok($l, 'Time::Piece', 'custom localtime via new again');
+
+#via clone
+my $l_clone = Time::Piece->new($l);
+isa_ok($l, 'Time::Piece', 'custom localtime via clone');
+cmp_ok("$l_clone", 'eq', "$l", 'Clones match');
index 18dae7d..2933058 100644 (file)
@@ -1,4 +1,4 @@
-use Test::More tests => 95;
+use Test::More tests => 102;
 
 my $is_win32 = ($^O =~ /Win32/);
 my $is_qnx = ($^O eq 'qnx');
@@ -128,7 +128,12 @@ cmp_ok($t->strftime('%W'), 'eq', '09'); # Sun cmp Mon
 cmp_ok($t->strftime('%y'), '==', 0); # should test with 1999
 cmp_ok($t->strftime('%Y'), 'eq', '2000');
 
-# %Z is locale and implementation dependent
+# %Z is locale and implementation dependent (s/// to the rescue)
+cmp_ok($t->strftime('%z'), 'eq', '+0000');
+cmp_ok($t->strftime('%%z%z'), 'eq', '%z+0000');
+cmp_ok($t->strftime('%Z'), 'eq', 'UTC');
+cmp_ok($t->strftime('%%Z%Z'), 'eq', '%ZUTC');
+
 # (there is NO standard for timezone names)
 cmp_ok($t->date(""), 'eq', '20000229');
 cmp_ok($t->ymd("") , 'eq', '20000229');
@@ -213,7 +218,7 @@ cmp_ok(Time::Piece->strptime("2002/06/10 23", '%Y/%m/%d %H')->week, '==', 24);
 # Test that strptime populates all relevant fields
 cmp_ok(Time::Piece->strptime("2002/07/10", '%Y/%m/%d')->wday,  '==', 4);
 cmp_ok(Time::Piece->strptime("2002/12/31", '%Y/%m/%d')->yday,  '==', 364);
-cmp_ok(Time::Piece->strptime("2002/07/10", '%Y/%m/%d')->isdst, '==', 0);
+cmp_ok(Time::Piece->strptime("2002/07/10", '%Y/%m/%d')->isdst, '==', -1);
 cmp_ok(Time::Piece->strptime("2002/07/10", '%Y/%m/%d')->day_of_week, '==', 3);
 
 is(
@@ -228,5 +233,20 @@ cmp_ok(
   951827696
 );
 
+#from Time::Piece::Plus
+#test reverse parsing
+my $now = localtime();
+my $strp_format = "%Y-%m-%d %H:%M:%S";
+
+my $now_str = $now->strftime($strp_format);
+
+my $now_parsed = $now->strptime($now_str, $strp_format);
+
+cmp_ok($now_parsed->epoch, '==', $now->epoch);
+cmp_ok($now_parsed->strftime($strp_format), 'eq', $now->strftime($strp_format));
+cmp_ok($now_parsed->strftime(), 'eq', $now->strftime());
+
+
 my $s = Time::Seconds->new(-691050);
 is($s->pretty, 'minus 7 days, 23 hours, 57 minutes, 30 seconds');
+
diff --git a/cpan/Time-Piece/t/02core_dst.t b/cpan/Time-Piece/t/02core_dst.t
new file mode 100644 (file)
index 0000000..2922514
--- /dev/null
@@ -0,0 +1,139 @@
+use Test::More tests => 60;
+
+my $is_win32 = ($^O =~ /Win32/);
+my $is_qnx = ($^O eq 'qnx');
+my $is_vos = ($^O eq 'vos');
+
+use Time::Piece;
+use Time::Seconds;
+
+#test using an epoch that can be DST
+
+my $t = gmtime(1373371631); # 2013-07-09T12:07:11
+
+is($t->sec,               11);
+is($t->second,            11);
+is($t->min,               07);
+is($t->minute,            07);
+is($t->hour,              12);
+is($t->mday,               9);
+is($t->day_of_month,       9);
+is($t->mon,                7);
+is($t->_mon,               6);
+is($t->monname,        'Jul');
+is($t->month,          'Jul');
+is($t->fullmonth,     'July');
+is($t->year,            2013);
+is($t->_year,            113);
+is($t->yy,              '13');
+
+cmp_ok($t->wday,        '==',         3);
+cmp_ok($t->_wday,       '==',         2);
+cmp_ok($t->day_of_week, '==',         2);
+cmp_ok($t->wdayname,    'eq',     'Tue');
+cmp_ok($t->day,         'eq',     'Tue');
+cmp_ok($t->fullday,     'eq', 'Tuesday');
+cmp_ok($t->yday,        '==',        189);
+cmp_ok($t->day_of_year, '==',        189);
+
+# In GMT there should be no daylight savings ever.
+cmp_ok($t->isdst, '==', 0);
+cmp_ok($t->epoch, '==',   1373371631);
+cmp_ok($t->hms,   'eq',   '12:07:11');
+cmp_ok($t->time,  'eq',   '12:07:11');
+cmp_ok($t->ymd,   'eq', '2013-07-09');
+cmp_ok($t->date,  'eq', '2013-07-09');
+cmp_ok($t->mdy,   'eq', '07-09-2013');
+cmp_ok($t->dmy,   'eq', '09-07-2013');
+cmp_ok($t->cdate, 'eq', 'Tue Jul  9 12:07:11 2013');
+cmp_ok("$t",      'eq', 'Tue Jul  9 12:07:11 2013');
+cmp_ok($t->datetime, 'eq','2013-07-09T12:07:11');
+cmp_ok($t->daylight_savings, '==', 0);
+
+
+cmp_ok($t->week, '==', 28);
+
+# strftime tests
+
+# %a, %A, %b, %B, %c are locale-dependent
+
+# %C is unportable: sometimes its like asctime(3) or date(1),
+# sometimes it's the century (and whether for 2000 the century is
+# 20 or 19, is fun, too..as far as I can read SUSv2 it should be 20.)
+cmp_ok($t->strftime('%d'), '==', 9);
+
+SKIP: {
+  skip "can't strftime %D, %R, %T or %e on Win32", 1 if $is_win32;
+  cmp_ok($t->strftime('%D'), 'eq', '07/09/13'); # Yech!
+}
+SKIP:{
+  skip "can't strftime %D, %R, %T or %e on Win32", 1 if $is_win32;
+  skip "can't strftime %e on QNX", 1 if $is_qnx;
+  cmp_ok($t->strftime('%e'), 'eq', ' 9');       # should test with < 10
+}
+
+# %h is locale-dependent
+cmp_ok($t->strftime('%H'), 'eq', '12'); # should test with < 10
+
+cmp_ok($t->strftime('%I'), 'eq', '12'); # should test with < 10
+cmp_ok($t->strftime('%j'), '==',  190 ); # why ->yday+1 ?
+cmp_ok($t->strftime('%M'), 'eq', '07'); # should test with < 10
+
+# %p, %P, and %r are not widely implemented,
+# and are possibly unportable (am or AM or a.m., and so on)
+
+SKIP: {
+  skip "can't strftime %R on Win32 or QNX", 1 if $is_win32 or $is_qnx;
+  cmp_ok($t->strftime('%R'), 'eq', '12:07');    # should test with > 12
+}
+
+ok($t->strftime('%S') eq '11'); # should test with < 10
+
+SKIP: {
+  skip "can't strftime %T on Win32", 1 if $is_win32;
+  cmp_ok($t->strftime('%T'), 'eq', '12:07:11'); # < 12 and > 12
+}
+
+# There are bugs in the implementation of %u in many platforms.
+# (e.g. Linux seems to think, despite the man page, that %u
+# 1-based on Sunday...)
+
+cmp_ok($t->strftime('%U'), 'eq', '27'); # Sun cmp Mon
+
+SKIP: {
+    skip "can't strftime %V on Win32 or QNX or VOS", 1 if $is_win32 or $is_qnx or $is_vos;
+    # is this test really broken on Mac OS? -- rjbs, 2006-02-08
+    cmp_ok($t->strftime('%V'), 'eq', '28'); # Sun cmp Mon
+}
+
+cmp_ok($t->strftime('%w'), '==', 2);
+cmp_ok($t->strftime('%W'), 'eq', '27'); # Sun cmp Mon
+
+# %x is locale and implementation dependent.
+
+cmp_ok($t->strftime('%y'), '==', 13); # should test with 1999
+cmp_ok($t->strftime('%Y'), 'eq', '2013');
+
+ok(not $t->is_leap_year); # should test more with different dates
+
+cmp_ok($t->month_last_day, '==', 31); # test more
+
+
+{
+    local $ENV{TZ} = "EST5EDT4";
+    Time::Piece::_tzset();
+    my $lt = localtime(1373371631); #2013-07-09T12:07:11
+    cmp_ok(scalar($lt->tzoffset), 'eq', '-14400');
+    cmp_ok($lt->strftime("%Y-%m-%d %H:%M:%S %Z"), 'eq', '2013-07-09 08:07:11 EDT');
+    like  ($lt->strftime("%z"), qr/-0400|EDT/); #windows: %Z and %z are the same
+
+    $lt = localtime(1357733231); #2013-01-09T12:07:11
+    cmp_ok(scalar($lt->tzoffset), 'eq', '-18000');
+    cmp_ok($lt->strftime("%Y-%m-%d %H:%M:%S %Z"), 'eq', '2013-01-09 07:07:11 EST');
+    like  ($lt->strftime("%z"), qr/-0500|EST/);
+}
+
+
+
+
+
index dce097a..d6e4315 100644 (file)
@@ -7,6 +7,9 @@ use warnings;
 
 use Test::More 'no_plan';
 
+use lib "t/lib";
+use Time::Piece::Twin;
+
 BEGIN { use_ok('Time::Piece'); }
 
 my $class = 'Time::Piece::Twin';
@@ -39,12 +42,7 @@ for my $method (qw(new localtime gmtime)) {
   isnt(ref $piece, 'Time::Piece::Twin', "it's not a Twin");
 }
 
-## below is our doppelgaenger package
-{
-  package Time::Piece::Twin;
-  use base qw(Time::Piece);
-  # this package is identical, but will be ->isa('Time::Piece::Twin');
-}
+
 
 {
   my $class = "Time::Piece::NumString";
diff --git a/cpan/Time-Piece/t/lib/Time/Piece/Twin.pm b/cpan/Time-Piece/t/lib/Time/Piece/Twin.pm
new file mode 100644 (file)
index 0000000..9798f83
--- /dev/null
@@ -0,0 +1,4 @@
+# this package is identical, but will be ->isa('Time::Piece::Twin');
+package Time::Piece::Twin;
+use base qw(Time::Piece);
+our $VERSION = "0.01";