1package Class::Date;
2our $AUTHORITY = 'cpan:YANICK';
3# ABSTRACT: Class for easy date and time manipulation
4$Class::Date::VERSION = '1.1.17';
5use 5.006;
6
7use strict;
8use vars qw(
9  @EXPORT_OK %EXPORT_TAGS @ISA
10  $DATE_FORMAT $DST_ADJUST $MONTH_BORDER_ADJUST $RANGE_CHECK
11  @NEW_FROM_SCALAR @ERROR_MESSAGES $WARNINGS
12  $DEFAULT_TIMEZONE $LOCAL_TIMEZONE $GMT_TIMEZONE
13  $NOTZ_TIMEZONE $RESTORE_TZ
14);
15use Carp;
16
17use Exporter;
18use Time::Local;
19use Class::Date::Const;
20use Scalar::Util qw(blessed);
21use POSIX;
22
23use Class::Date::Rel;
24use Class::Date::Invalid;
25
26BEGIN {
27    $WARNINGS = 1 if !defined $WARNINGS;
28    *timelocal = *Time::Local::timelocal_nocheck;
29    *timegm = *Time::Local::timegm_nocheck;
30
31    @ISA=qw(Exporter);
32    %EXPORT_TAGS = ( errors => $Class::Date::Const::EXPORT_TAGS{errors});
33    @EXPORT_OK = (qw( date localdate gmdate now @ERROR_MESSAGES),
34        @{$EXPORT_TAGS{errors}});
35
36    *strftime_xs = *POSIX::strftime;
37    *tzset_xs = *POSIX::tzset;
38    *tzname_xs = *POSIX::tzname;
39}
40
41$GMT_TIMEZONE = 'GMT';
42$DST_ADJUST = 1;
43$MONTH_BORDER_ADJUST = 0;
44$RANGE_CHECK = 0;
45$RESTORE_TZ = 1;
46$DATE_FORMAT="%Y-%m-%d %H:%M:%S";
47
48sub _set_tz { my ($tz) = @_;
49    my $lasttz = $ENV{TZ};
50    if (!defined $tz || $tz eq $NOTZ_TIMEZONE) {
51        # warn "_set_tz: deleting TZ\n";
52        delete $ENV{TZ};
53        Env::C::unsetenv('TZ') if exists $INC{"Env/C.pm"};
54    } else {
55        # warn "_set_tz: setting TZ to $tz\n";
56        $ENV{TZ} = $tz;
57        Env::C::setenv('TZ', $tz) if exists $INC{"Env/C.pm"};
58    }
59    tzset_xs();
60    return $lasttz;
61}
62
63sub _set_temp_tz { my ($tz, $sub) = @_;
64    my $lasttz = _set_tz($tz);
65    my $retval = eval { $sub->(); };
66    _set_tz($lasttz) if $RESTORE_TZ;
67    die $@ if $@;
68    return $retval;
69}
70
71tzset_xs();
72$LOCAL_TIMEZONE = $DEFAULT_TIMEZONE = local_timezone();
73{
74    my $last_tz = _set_tz(undef);
75    $NOTZ_TIMEZONE = local_timezone();
76    _set_tz($last_tz);
77}
78# warn "LOCAL: $LOCAL_TIMEZONE, NOTZ: $NOTZ_TIMEZONE\n";
79
80# this method is used to determine what is the package name of the relative
81# time class. It is used at the operators. You only need to redefine it if
82# you want to derive both Class::Date and Class::Date::Rel.
83# Look at the Class::Date::Rel::ClassDate also.
84use constant ClassDateRel => "Class::Date::Rel";
85use constant ClassDateInvalid => "Class::Date::Invalid";
86
87use overload
88  '""'     => "string",
89  '-'      => "subtract",
90  '+'      => "add",
91  '<=>'    => "compare",
92  'cmp'    => "compare",
93  fallback => 1;
94
95sub date ($;$) { my ($date,$tz)=@_;
96  return __PACKAGE__ -> new($date,$tz);
97}
98
99sub now () { date(time); }
100
101sub localdate ($) { date($_[0] || time, $LOCAL_TIMEZONE) }
102
103sub gmdate    ($) { date($_[0] || time, $GMT_TIMEZONE) }
104
105sub import {
106  my $package=shift;
107  my @exported;
108  foreach my $symbol (@_) {
109    if ($symbol eq '-DateParse') {
110      if (!$Class::Date::DateParse++) {
111        if ( eval { require Date::Parse } ) {
112            push @NEW_FROM_SCALAR,\&new_from_scalar_date_parse;
113        } else {
114            warn "Date::Parse is not available, although it is requested by Class::Date\n"
115                if $WARNINGS;
116        }
117      }
118    } elsif ($symbol eq '-EnvC') {
119      if (!$Class::Date::EnvC++) {
120        if ( !eval { require Env::C } ) {
121          warn "Env::C is not available, although it is requested by Class::Date\n"
122            if $WARNINGS;
123        }
124      }
125    } else {
126      push @exported,$symbol;
127    }
128  };
129  $package->export_to_level(1,$package,@exported);
130}
131
132sub new { my ($proto,$time,$tz)=@_;
133  my $class = ref($proto) || $proto;
134
135  # if the prototype is an object, not a class, then the timezone will be
136  # the same
137  $tz = $proto->[c_tz]
138    if defined($time) && !defined $tz && blessed($proto) && $proto->isa( __PACKAGE__ );
139
140  # Default timezone is used if the timezone cannot be determined otherwise
141  $tz = $DEFAULT_TIMEZONE if !defined $tz;
142
143  return $proto->new_invalid(E_UNDEFINED,"") if !defined $time;
144  if (blessed($time) && $time->isa( __PACKAGE__ ) ) {
145    return $class->new_copy($time,$tz);
146  } elsif (blessed($time) && $time->isa('Class::Date::Rel')) {
147    return $class->new_from_scalar($time,$tz);
148  } elsif (ref($time) eq 'ARRAY') {
149    return $class->new_from_array($time,$tz);
150  } elsif (ref($time) eq 'SCALAR') {
151    return $class->new_from_scalar($$time,$tz);
152  } elsif (ref($time) eq 'HASH') {
153    return $class->new_from_hash($time,$tz);
154  } else {
155    return $class->new_from_scalar($time,$tz);
156  }
157}
158
159sub new_copy { my ($s,$input)=@_;
160  my $new_object=[ @$input ];
161  # we don't mind $isgmt!
162  return bless($new_object, ref($s) || $s);
163}
164
165sub new_from_array { my ($s,$time,$tz) = @_;
166  my ($y,$m,$d,$hh,$mm,$ss) = @$time;
167  my $obj= [
168    ($y||2000)-1900, ($m||1)-1, $d||1,
169    $hh||0         , $mm||0   , $ss||0
170  ];
171  $obj->[c_tz]=$tz;
172  bless $obj, ref($s) || $s;
173  $obj->_recalc_from_struct;
174  return $obj;
175}
176
177sub new_from_hash { my ($s,$time,$tz) = @_;
178  $s->new_from_array(_array_from_hash($time),$tz);
179}
180
181sub _array_from_hash { my ($val)=@_;
182  [
183    $val->{year} || ($val->{_year} ? $val->{_year} + 1900 : 0 ),
184    $val->{mon} || $val->{month} || ( $val->{_mon} ? $val->{_mon} + 1 : 0 ),
185    $val->{day}   || $val->{mday} || $val->{day_of_month},
186    $val->{hour},
187    exists $val->{min} ? $val->{min} : $val->{minute},
188    exists $val->{sec} ? $val->{sec} : $val->{second},
189  ];
190}
191
192sub new_from_scalar { my ($s,$time,$tz)=@_;
193  for (my $i=0;$i<@NEW_FROM_SCALAR;$i++) {
194    my $ret=$NEW_FROM_SCALAR[$i]->($s,$time,$tz);
195    return $ret if defined $ret;
196  }
197  return $s->new_invalid(E_UNPARSABLE,$time);
198}
199
200sub new_from_scalar_internal { my ($s,$time,$tz) = @_;
201  return undef if !$time;
202
203  if ($time eq 'now') {
204    # now string
205    my $obj=bless [], ref($s) || $s;
206    $obj->[c_epoch]=time;
207    $obj->[c_tz]=$tz;
208    $obj->_recalc_from_epoch;
209    return $obj;
210  } elsif ($time =~ /^\s*(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)\d*\s*$/) {
211    # mysql timestamp
212    my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$4,$5,$6);
213    return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss],$tz);
214  } elsif ($time =~ /^\s*( \-? \d+ (\.\d+ )? )\s*$/x) {
215    # epoch secs
216    my $obj=bless [], ref($s) || $s;
217    $obj->[c_epoch]=$1;
218    $obj->[c_tz]=$tz;
219    $obj->_recalc_from_epoch;
220    return $obj;
221  } elsif ($time =~ m{ ^\s* ( \d{0,4} ) - ( \d\d? ) - ( \d\d? )
222     ( (?: T|\s+ ) ( \d\d? ) : ( \d\d? ) ( : ( \d\d?  ) (\.\d+)?)? )? }x) {
223    my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$5,$6,$8);
224    # ISO(-like) date
225    return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss],$tz);
226  } else {
227    return undef;
228  }
229}
230
231push @NEW_FROM_SCALAR,\&new_from_scalar_internal;
232
233sub new_from_scalar_date_parse { my ($s,$date,$tz)=@_;
234    my $lt;
235    my ($ss, $mm, $hh, $day, $month, $year, $zone) =
236        Date::Parse::strptime($date);
237    $zone = $tz if !defined $zone;
238    if ($zone eq $GMT_TIMEZONE) {
239        _set_temp_tz($zone, sub {
240            $ss     = ($lt ||= [ gmtime ])->[0]  if !defined $ss;
241            $mm     = ($lt ||= [ gmtime ])->[1]  if !defined $mm;
242            $hh     = ($lt ||= [ gmtime ])->[2]  if !defined $hh;
243            $day    = ($lt ||= [ gmtime ])->[3] if !defined $day;
244            $month  = ($lt ||= [ gmtime ])->[4] if !defined $month;
245            $year   = ($lt ||= [ gmtime ])->[5] if !defined $year;
246        });
247    } else {
248        _set_temp_tz($zone, sub {
249            $ss     = ($lt ||= [ localtime ])->[0]  if !defined $ss;
250            $mm     = ($lt ||= [ localtime ])->[1]  if !defined $mm;
251            $hh     = ($lt ||= [ localtime ])->[2]  if !defined $hh;
252            $day    = ($lt ||= [ localtime ])->[3] if !defined $day;
253            $month  = ($lt ||= [ localtime ])->[4] if !defined $month;
254            $year   = ($lt ||= [ localtime ])->[5] if !defined $year;
255        });
256    }
257    return $s->new_from_array( [$year+1900, $month+1, $day,
258        $hh, $mm, $ss], $zone);
259}
260
261sub _check_sum { my ($s) = @_;
262  my $sum=0; $sum += $_ || 0 foreach @{$s}[c_year .. c_sec];
263  return $sum;
264}
265
266sub _recalc_from_struct {
267    my $s = shift;
268    $s->[c_isdst] = -1;
269    $s->[c_wday]  = 0;
270    $s->[c_yday]  = 0;
271    $s->[c_epoch] = 0; # these are required to suppress warinngs;
272    eval {
273        local $SIG{__WARN__} = sub { };
274        my $timecalc = $s->[c_tz] eq $GMT_TIMEZONE ?
275            \&timegm : \&timelocal;
276        _set_temp_tz($s->[c_tz],
277            sub {
278                $s->[c_epoch] = $timecalc->(
279                    @{$s}[c_sec,c_min,c_hour,c_day,c_mon],
280                    $s->[c_year] + 1900);
281            }
282        );
283    };
284    return $s->_set_invalid(E_INVALID,$@) if $@;
285    my $sum = $s->_check_sum;
286    $s->_recalc_from_epoch;
287    @$s[c_error,c_errmsg] = (($s->_check_sum != $sum ? E_RANGE : 0), "");
288    return $s->_set_invalid(E_RANGE,"") if $RANGE_CHECK && $s->[c_error];
289    return 1;
290}
291
292sub _recalc_from_epoch { my ($s) = @_;
293    _set_temp_tz($s->[c_tz],
294        sub {
295            @{$s}[c_year..c_isdst] =
296                ($s->[c_tz] eq $GMT_TIMEZONE ?
297                    gmtime($s->[c_epoch]) : localtime($s->[c_epoch]))
298                    [5,4,3,2,1,0,6,7,8];
299        }
300    )
301}
302
303my $SETHASH = {
304    year   => sub { shift->[c_year] = shift() - 1900 },
305    _year  => sub { shift->[c_year] = shift },
306    month  => sub { shift->[c_mon] = shift() - 1 },
307    _month => sub { shift->[c_mon] = shift },
308    day    => sub { shift->[c_day] = shift },
309    hour   => sub { shift->[c_hour] = shift },
310    min    => sub { shift->[c_min] = shift },
311    sec    => sub { shift->[c_sec] = shift },
312    tz     => sub { shift->[c_tz] = shift },
313};
314$SETHASH->{mon}    = $SETHASH->{month};
315$SETHASH->{_mon}   = $SETHASH->{_month};
316$SETHASH->{mday}   = $SETHASH->{day_of_month} = $SETHASH->{day};
317$SETHASH->{minute} = $SETHASH->{min};
318$SETHASH->{second} = $SETHASH->{sec};
319
320sub clone {
321    my $s = shift;
322    my $new_date = $s->new_copy($s);
323    while (@_) {
324        my $key = shift;
325        my $value = shift;
326        $SETHASH->{$key}->($value,$new_date);
327    };
328    $new_date->_recalc_from_struct;
329    return $new_date;
330}
331
332*set = *clone; # compatibility
333
334sub year     { shift->[c_year]  +1900 }
335sub _year    { shift->[c_year]  }
336sub yr       { shift->[c_year]  % 100 }
337sub mon      { shift->[c_mon]   +1 }
338*month       = *mon;
339sub _mon     { shift->[c_mon]   }
340*_month      = *_mon;
341sub day      { shift->[c_day]   }
342*day_of_month= *mday = *day;
343sub hour     { shift->[c_hour]  }
344sub min      { shift->[c_min]   }
345*minute      = *min;
346sub sec      { shift->[c_sec]   }
347*second      = *sec;
348sub wday     { shift->[c_wday]  + 1 }
349sub _wday    { shift->[c_wday]  }
350*day_of_week = *_wday;
351sub yday     { shift->[c_yday]  }
352*day_of_year = *yday;
353sub isdst    { shift->[c_isdst] }
354*daylight_savings = \&isdst;
355sub epoch    { shift->[c_epoch] }
356*as_sec      = *epoch; # for compatibility
357sub tz       { shift->[c_tz] }
358sub tzdst    { shift->strftime("%Z") }
359
360sub monname  { shift->strftime('%B') }
361*monthname   = *monname;
362sub wdayname { shift->strftime('%A') }
363*day_of_weekname= *wdayname;
364
365sub error { shift->[c_error] }
366sub errmsg { my ($s) = @_;
367    sprintf $ERROR_MESSAGES[ $s->[c_error] ]."\n", $s->[c_errmsg]
368}
369*errstr = *errmsg;
370
371sub new_invalid { my ($proto,$error,$errmsg) = @_;
372    bless([],ref($proto) || $proto)->_set_invalid($error,$errmsg);
373}
374
375sub _set_invalid { my ($s,$error,$errmsg) = @_;
376    bless($s,$s->ClassDateInvalid);
377    @$s = ();
378    @$s[ci_error, ci_errmsg] = ($error,$errmsg);
379    return $s;
380}
381
382sub ampm { my ($s) = @_;
383    return $s->[c_hour] < 12 ? "AM" : "PM";
384}
385
386sub meridiam { my ($s) = @_;
387    my $hour = $s->[c_hour] % 12;
388    if( $hour == 0 ) { $hour = 12; }
389    sprintf('%02d:%02d %s', $hour, $s->[c_min], $s->ampm);
390}
391
392sub hms { sprintf('%02d:%02d:%02d', @{ shift() }[c_hour,c_min,c_sec]) }
393
394sub ymd { my ($s)=@_;
395  sprintf('%04d/%02d/%02d', $s->year, $s->mon, $s->[c_day])
396}
397
398sub mdy { my ($s)=@_;
399  sprintf('%02d/%02d/%04d', $s->mon, $s->[c_day], $s->year)
400}
401
402sub dmy { my ($s)=@_;
403  sprintf('%02d/%02d/%04d', $s->[c_day], $s->mon, $s->year)
404}
405
406sub array { my ($s)=@_;
407  my @return=@{$s}[c_year .. c_sec];
408  $return[c_year]+=1900;
409  $return[c_mon]+=1;
410  @return;
411}
412
413sub aref { return [ shift()->array ] }
414*as_array = *aref;
415
416sub struct {
417  return ( @{ shift() }
418    [c_sec,c_min,c_hour,c_day,c_mon,c_year,c_wday,c_yday,c_isdst] )
419}
420
421sub sref { return [ shift()->struct ] }
422
423sub href { my ($s)=@_;
424  my @struct=$s->struct;
425  my $h={};
426  foreach my $key (qw(sec min hour day _month _year wday yday isdst)) {
427    $h->{$key}=shift @struct;
428  }
429  $h->{epoch} = $s->[c_epoch];
430  $h->{year} = 1900 + $h->{_year};
431  $h->{month} = $h->{_month} + 1;
432  $h->{minute} = $h->{min};
433  return $h;
434}
435
436*as_hash=*href;
437
438sub hash { return %{ shift->href } }
439
440# Thanks to Tony Olekshy <olekshy@cs.ualberta.ca> for this algorithm
441# ripped from Time::Object by Matt Sergeant
442sub tzoffset { my ($s)=@_;
443    my $epoch = $s->[c_epoch];
444    my $j = sub { # Tweaked Julian day number algorithm.
445        my ($s,$n,$h,$d,$m,$y) = @_; $m += 1; $y += 1900;
446        # Standard Julian day number algorithm without constant.
447        my $y1 = $m > 2 ? $y : $y - 1;
448        my $m1 = $m > 2 ? $m + 1 : $m + 13;
449        my $day = int(365.25 * $y1) + int(30.6001 * $m1) + $d;
450        # Modify to include hours/mins/secs in floating portion.
451        return $day + ($h + ($n + $s / 60) / 60) / 24;
452    };
453    # Compute floating offset in hours.
454    my $delta = _set_temp_tz($s->[c_tz],
455        sub {
456            24 * (&$j(localtime $epoch) - &$j(gmtime $epoch));
457        }
458    );
459    # Return value in seconds rounded to nearest minute.
460    return int($delta * 60 + ($delta >= 0 ? 0.5 : -0.5)) * 60;
461}
462
463sub month_begin { my ($s) = @_;
464  my $aref = $s->aref;
465  $aref->[2] = 1;
466  return $s->new($aref);
467}
468
469sub month_end { my ($s)=@_;
470  return $s->clone(day => 1)+'1M'-'1D';
471}
472
473sub days_in_month {
474  shift->month_end->mday;
475}
476
477sub is_leap_year { my ($s) = @_;
478    my $new_date;
479    eval {
480        $new_date = $s->new([$s->year, 2, 29],$s->tz);
481    } or return 0;
482    return $new_date->day == 29;
483}
484
485sub strftime { my ($s,$format)=@_;
486  $format ||= "%a, %d %b %Y %H:%M:%S %Z";
487  my $fmt = _set_temp_tz($s->[c_tz], sub { strftime_xs($format,$s->struct) } );
488  return $fmt;
489}
490
491sub string { my ($s) = @_;
492  $s->strftime($DATE_FORMAT);
493}
494
495sub subtract { my ($s,$rhs)=@_;
496  if (blessed($rhs) && $rhs->isa( __PACKAGE__ )) {
497    my $dst_adjust = 0;
498    $dst_adjust = 60*60*( $s->[c_isdst]-$rhs->[c_isdst] ) if $DST_ADJUST;
499    return $s->ClassDateRel->new($s->[c_epoch]-$rhs->[c_epoch]+$dst_adjust);
500  } elsif (blessed($rhs) && $rhs->isa("Class::Date::Rel")) {
501    return $s->add(-$rhs);
502  } elsif ($rhs) {
503    return $s->add($s->ClassDateRel->new($rhs)->neg);
504  } else {
505    return $s;
506  }
507}
508
509sub add { my ($s,$rhs)=@_;
510  local $RANGE_CHECK;
511  $rhs=$s->ClassDateRel->new($rhs) unless blessed($rhs) && $rhs->isa('Class::Date::Rel');
512
513  return $s unless blessed($rhs) && $rhs->isa('Class::Date::Rel');
514
515  # adding seconds
516  my $retval= $rhs->[cs_sec] ?
517    $s->new_from_scalar($s->[c_epoch]+$rhs->[cs_sec],$s->[c_tz]) :
518    $s->new_copy($s);
519
520  # adjust DST if necessary
521  if ( $DST_ADJUST && (my $dstdiff=$retval->[c_isdst]-$s->[c_isdst]))  {
522    $retval->[c_epoch] -= $dstdiff*60*60;
523    $retval->_recalc_from_epoch;
524  }
525
526  # adding months
527  if ($rhs->[cs_mon]) {
528    $retval->[c_mon]+=$rhs->[cs_mon];
529    my $year_diff= $retval->[c_mon]>0 ? # instead of POSIX::floor
530      int ($retval->[c_mon]/12) :
531      int (($retval->[c_mon]-11)/12);
532    $retval->[c_mon]  -= 12*$year_diff;
533    my $expected_month = $retval->[c_mon];
534    $retval->[c_year] += $year_diff;
535    $retval->_recalc_from_struct;
536
537    # adjust month border if necessary
538    if ($MONTH_BORDER_ADJUST && $retval && $expected_month != $retval->[c_mon]) {
539      $retval->[c_epoch] -= $retval->[c_day]*60*60*24;
540      $retval->_recalc_from_epoch;
541    }
542  }
543
544  # sigh! We have finished!
545  return $retval;
546}
547
548sub trunc { my ($s)=@_;
549  return $s->new_from_array([$s->year,$s->month,$s->day,0,0,0],$s->[c_tz]);
550}
551
552*truncate = *trunc;
553
554sub get_epochs {
555  my ($lhs,$rhs,$reverse)=@_;
556  unless (blessed($rhs) && $rhs->isa( __PACKAGE__ )) {
557    $rhs = $lhs->new($rhs);
558  }
559  my $repoch= $rhs ? $rhs->epoch : 0;
560  return $repoch, $lhs->epoch if $reverse;
561  return $lhs->epoch, $repoch;
562}
563
564sub compare {
565  my ($lhs, $rhs) = get_epochs(@_);
566  return $lhs <=> $rhs;
567}
568
569sub local_timezone {
570    return (tzname_xs())[0];
571}
572
573sub to_tz { my ($s, $tz) = @_;
574    return $s->new($s->epoch, $tz);
575}
5761;
577
578__END__
579
580=pod
581
582=encoding UTF-8
583
584=head1 NAME
585
586Class::Date - Class for easy date and time manipulation
587
588=head1 VERSION
589
590version 1.1.17
591
592=head1 SYNOPSIS
593
594  use Class::Date qw(:errors date localdate gmdate now -DateParse -EnvC);
595
596  # creating absolute date object (local time)
597  $date = Class::Date->new( [$year,$month,$day,$hour,$min,$sec]);
598  $date = date [$year,$month,$day,$hour,$min,$sec];
599    # ^- "date" is an exportable function, the same as Class::Date->new
600  $date = date { year => $year, month => $month, day => $day,
601    hour => $hour, min => $min, sec => $sec };
602  $date = date "2001-11-12 07:13:12";
603  $date = localdate "2001-12-11";
604  $date = now;                      #  the same as date(time)
605  $date = date($other_date_object); # cloning
606  ...
607
608  # creating absolute date object (GMT)
609  $date = Class::Date->new( [$year,$month,$day,$hour,$min,$sec],'GMT');
610  $date = gmdate "2001-11-12 17:13";
611  ...
612
613  # creating absolute date object in any other timezone
614  $date = Class::Date->new( [$year,$month,$day,$hour,$min,$sec],'Iceland' );
615  $date = date "2001-11-12 17:13", 'Iceland';
616  $date2 = $date->new([$y2, $m2, $d2, $h2, $m2, $s2]);
617    # ^- timezone is inherited from the $date object
618
619  # creating relative date object
620  # (normally you don't need to create this object explicitly)
621  $reldate = Class::Date::Rel->new( "3Y 1M 3D 6h 2m 4s" );
622  $reldate = Class::Date::Rel->new( "6Y" );
623  $reldate = Class::Date::Rel->new( $secs );  # secs
624  $reldate = Class::Date::Rel->new( [$year,$month,$day,$hour,$min,$sec] );
625  $reldate = Class::Date::Rel->new( { year => $year, month => $month, day => $day,
626    hour => $hour, min => $min, sec => $sec } );
627  $reldate = Class::Date::Rel->new( "2001-11-12 07:13:12" );
628  $reldate = Class::Date::Rel->new( "2001-12-11" );
629
630  # getting values of an absolute date object
631  $date;              # prints the date in default output format (see below)
632  $date->year;        # year, e.g: 2001
633  $date->_year;       # year - 1900, e.g. 101
634  $date->yr;          # 2-digit year 0-99, e.g 1
635  $date->mon;         # month 1..12
636  $date->month;       # same as prev.
637  $date->_mon;        # month 0..11
638  $date->_month;      # same as prev.
639  $date->day;         # day of month
640  $date->mday;        # day of month
641  $date->day_of_month;# same as prev.
642  $date->hour;
643  $date->min;
644  $date->minute;      # same as prev.
645  $date->sec;
646  $date->second;      # same as prev.
647  $date->wday;        # 1 = Sunday
648  $date->_wday;       # 0 = Sunday
649  $date->day_of_week; # same as prev.
650  $date->yday;
651  $date->day_of_year; # same as prev.
652  $date->isdst;       # DST?
653  $date->daylight_savings; # same as prev.
654  $date->epoch;       # UNIX time_t
655  $date->monname;     # name of month, eg: March
656  $date->monthname;   # same as prev.
657  $date->wdayname;    # Thursday
658  $date->day_of_weekname # same as prev.
659  $date->hms          # 01:23:45
660  $date->ymd          # 2000/02/29
661  $date->mdy          # 02/29/2000
662  $date->dmy          # 29/02/2000
663  $date->meridiam     # 01:23 AM
664  $date->ampm         # AM/PM
665  $date->string       # 2000-02-29 12:21:11 (format can be changed, look below)
666  "$date"             # same as prev.
667  $date->tzoffset     # timezone-offset
668  $date->strftime($format) # POSIX strftime (without the huge POSIX.pm)
669  $date->tz           # returns the base timezone as you specify, eg: CET
670  $date->tzdst        # returns the real timezone with dst information, eg: CEST
671
672  ($year,$month,$day,$hour,$min,$sec)=$date->array;
673  ($year,$month,$day,$hour,$min,$sec)=@{ $date->aref };
674  # !! $year: 1900-, $month: 1-12
675
676  ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=$date->struct;
677  ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=@{ $date->sref };
678  # !! $year: 0-, $month: 0-11
679
680  $hash=$date->href; # $href can be reused as a constructor
681  print $hash->{year}."-".$hash->{month}. ... $hash->{sec} ... ;
682
683  %hash=$date->hash;
684  # !! $hash{year}: 1900-, $hash{month}: 1-12
685
686  $date->month_begin  # First day of the month (date object)
687  $date->month_end    # Last day of the month
688  $date->days_in_month # 28..31
689
690  # constructing new date based on an existing one:
691  $new_date = $date->clone;
692  $new_date = $date->clone( year => 1977, sec => 14 );
693  # valid keys: year, _year, month, mon, _month, _mon, day, mday, day_of_month,
694  #             hour, min, minute, sec, second, tz
695  # constructing a new date, which is the same as the original, but in
696  # another timezone:
697  $new_date = $date->to_tz('Iceland');
698
699  # changing date format
700  {
701    local $Class::Date::DATE_FORMAT="%Y%m%d%H%M%S";
702    print $date       # result: 20011222000000
703    $Class::Date::DATE_FORMAT=undef;
704    print $date       # result: Thu Oct 13 04:54:34 1994
705    $Class::Date::DATE_FORMAT="%Y/%m/%d"
706    print $date       # result: 1994/10/13
707  }
708
709  # error handling
710  $a = date($date_string);
711  if ($a) { # valid date
712    ...
713  } else { # invalid date
714    if ($a->error == E_INVALID) { ... }
715    print $a->errstr;
716  }
717
718  # adjusting DST in calculations  (see the doc)
719  $Class::Date::DST_ADJUST = 1; # this is the default
720  $Class::Date::DST_ADJUST = 0;
721
722  # "month-border adjust" flag
723  $Class::Date::MONTH_BORDER_ADJUST = 0; # this is the default
724  print date("2001-01-31")+'1M'; # will print 2001-03-03
725  $Class::Date::MONTH_BORDER_ADJUST = 1;
726  print date("2001-01-31")+'1M'; # will print 2001-02-28
727
728  # date range check
729  $Class::Date::RANGE_CHECK = 0; # this is the default
730  print date("2001-02-31"); # will print 2001-03-03
731  $Class::Date::RANGE_CHECK = 1;
732  print date("2001-02-31"); # will print nothing
733
734  # getting values of a relative date object
735  $reldate;              # reldate in seconds (assumed 1 month = 2_629_744 secs)
736  $reldate->year;
737  $reldate->mon;
738  $reldate->month;       # same as prev.
739  $reldate->day;
740  $reldate->hour;
741  $reldate->min;
742  $reldate->minute;      # same as prev.
743  $reldate->sec;         # same as $reldate
744  $reldate->second;      # same as prev.
745  $reldate->sec_part;    # "second" part of the relative date
746  $reldate->mon_part;    # "month"  part of the relative date
747
748  # arithmetic with dates:
749  print date([2001,12,11,4,5,6])->truncate;
750                               # will print "2001-12-11"
751  $new_date = $date+$reldate;
752  $date2    = $date+'3Y 2D';   # 3 Years and 2 days
753  $date3    = $date+[1,2,3];   # $date plus 1 year, 2 months, 3 days
754  $date4    = $date+'3-1-5'    # $date plus 3 years, 1 months, 5 days
755
756  $new_date = $date-$reldate;
757  $date2    = $date-'3Y';      # 3 Yearss
758  $date3    = $date-[1,2,3];   # $date minus 1 year, 2 months, 3 days
759  $date4    = $date-'3-1-5'    # $date minus 3 years, 1 month, 5 days
760
761  $new_reldate = $date1-$date2;
762  $reldate2 = Class::Date->new('2000-11-12')-'2000-11-10';
763  $reldate3    = $date3-'1977-11-10';
764
765  $days_between = (Class::Date->new('2001-11-12')-'2001-07-04')->day;
766
767  # comparison between absolute dates
768  print $date1 > $date2 ? "I am older" : "I am younger";
769
770  # comparison between relative dates
771  print $reldate1 > $reldate2 ? "I am faster" : "I am slower";
772
773  # Adding / Subtracting months and years are sometimes tricky:
774  print date("2001-01-29") + '1M' - '1M'; # gives "2001-02-01"
775  print date("2000-02-29") + '1Y' - '1Y'; # gives "2000-03-01"
776
777  # Named interface ($date2 does not necessary to be a Class::Date object)
778  $date1->string;               # same as $date1 in scalar context
779  $date1->subtract($date2);     # same as $date1 - $date2
780  $date1->add($date2);          # same as $date1 + $date2
781  $date1->compare($date2);      # same as $date1 <=> $date2
782
783  $reldate1->sec;               # same as $reldate1 in numeric or scalar context
784  $reldate1->compare($reldate2);# same as $reldate1 <=> $reldate2
785  $reldate1->add($reldate2);    # same as $reldate1 + $reldate2
786  $reldate1->neg                # used for subtraction
787
788  # Disabling Class::Date warnings at load time
789  BEGIN { $Class::Date::WARNINGS=0; }
790  use Class::Date;
791
792=head1 DESCRIPTION
793
794This module is intended to provide a general-purpose date and datetime type
795for perl. You have a Class::Date class for absolute date and datetime, and have
796a Class::Date::Rel class for relative dates.
797
798You can use "+", "-", "<" and ">" operators as with native perl data types.
799
800Note that this module is fairly ancient and dusty. You
801might want to take a look at L<DateTime> and its related
802modules for a more standard, and maintained, Perl date
803manipulation solution.
804
805=head1 USAGE
806
807If you want to use a date object, you need to do the following:
808
809  - create a new object
810  - do some operations (+, -, comparison)
811  - get result back
812
813=head2 Creating a new date object
814
815You can create a date object by the "date", "localdate" or "gmdate" function,
816or by calling the Class::Date constructor.
817
818"date" and "Class::Date->new" are equivalent, both has two arguments: The
819date and the timezone.
820
821  $date1= date [2000,11,12];
822  $date2= Class::Date->new([2000,06,11,13,11,22],'GMT');
823  $date2= $date1->new([2000,06,11,13,11,22]);
824
825If the timezone information is omitted, then it first check if "new" is
826called as an object method or a class method. If it is an object method,
827then it inherits the timezone from the base object, otherwise the default
828timezone is used ($Class::Date::DEFAULT_TIMEZONE), which is usually set to
829the local timezone (which is stored in $Class::Date::LOCAL_TIMEZONE). These
830two variables are set only once to the value, which is returned by the
831Class::Date::local_timezone() function. You can change these values
832whenever you want.
833
834"localdate $x" is equivalent to "date $x, $Class::Date::LOCAL_TIMEZONE",
835"gmdate $x" is equivalent to "date $x, $Class::Date::GMT_TIMEZONE".
836
837$Class::Date::GMT_TIMEZONE is set to 'GMT' by default.
838
839  $date1= localdate [2000,11,12];
840  $date2= gmdate [2000,4,2,3,33,33];
841
842  $date = localdate(time);
843
844The format of the accepted input date can be:
845
846=over 4
847
848=item [$year,$month,$day,$hour,$min,$sec]
849
850An array reference with 6 elements. The missing elements have default
851values (year: 2000, month, day: 1, hour, min, sec: 0)
852
853=item { year => $year, month => $month, day => $day, hour => $hour, min => $min, sec => $sec }
854
855A hash reference with the same 6 elements as above.
856
857=item "YYYYMMDDhhmmss"
858
859A mysql-style timestamp value, which consist of at least 14 digit.
860
861=item "973897262"
862
863A valid 32-bit integer: This is parsed as a unix time.
864
865=item "YYYY-MM-DD hh:mm:ss"
866
867A standard ISO(-like) date format. Additional ".fraction" part is ignored,
868":ss" can be omitted.
869
870=item additional input formats
871
872You can specify "-DateParse" as  an import parameter, e.g:
873
874  use Class::Date qw(date -DateParse);
875
876With this, the module will try to load Date::Parse module, and if it find it then all
877these formats can be used as an input. Please refer to the Date::Parse
878documentation.
879
880=back
881
882=head2 Operations
883
884=over 4
885
886=item addition
887
888You can add the following to a Class::Date object:
889
890  - a valid Class::Date::Rel object
891  - anything, that can be used for creating a new Class::Date::Rel object
892
893It means that you don't need to create a new Class::Date::Rel object every
894time when you add something to the Class::Date object, it creates them
895automatically:
896
897  $date= Class::Date->new('2001-12-11')+Class::Date::Rel->new('3Y');
898
899is the same as:
900
901  $date= date('2001-12-11')+'3Y';
902
903You can provide a Class::Date::Rel object in the following form:
904
905=over 4
906
907=item array ref
908
909The same format as seen in Class::Date format, except the default values are
910different: all zero.
911
912=item hash ref
913
914The same format as seen in Class::Date format, except the default values are
915different: all zero.
916
917=item "973897262"
918
919A valid 32-bit integer is parsed as seconds.
920
921=item "YYYY-MM-DD hh:mm:ss"
922
923A standard ISO date format, but this is parsed as relative date date and time,
924so month, day and year can be zero (and defaults to zero).
925
926=item "12Y 6M 6D 20h 12m 5s"
927
928This special string can be used if you don't want to use the ISO format. This
929string consists of whitespace separated tags, each tag consists of a number and
930a unit. The units can be:
931
932  Y: year
933  M: month
934  D: day
935  h: hour
936  m: min
937  s: sec
938
939The number and unit must be written with no space between them.
940
941=back
942
943=item substraction
944
945The same rules are true for substraction, except you can substract
946two Class::Date object from each other, and you will get a Class::Date::Rel
947object:
948
949  $reldate=$date1-$date2;
950  $reldate=date('2001-11-12 12:11:07')-date('2001-10-07 10:3:21');
951
952In this case, the "month" field of the $reldate object will be 0,
953and the other fields will contain the difference between two dates;
954
955=item comparison
956
957You can compare two Class::Date objects, or one Class::Date object and
958another data, which can be used for creating a new Class::Data object.
959
960It means that you don't need to bless both objects, one of them can be a
961simple string, array ref, hash ref, etc (see how to create a date object).
962
963  if ( date('2001-11-12') > date('2000-11-11') ) { ... }
964
965or
966
967  if ( date('2001-11-12') > '2000-11-11' ) { ... }
968
969=item truncate
970
971You can chop the time value from this object (set hour, min and sec to 0)
972with the "truncate" or "trunc" method. It does not modify the specified
973object, it returns with a new one.
974
975=item clone
976
977You can create new date object based on an existing one, by using the "clone"
978method. Note, this DOES NOT modify the base object.
979
980  $new_date = $date->clone( year => 2001, hour => 14 );
981
982The valid keys are: year, _year, month, mon, _month, _mon, day, mday,
983day_of_month, hour, min, minute, sec, second, tz.
984
985There is a "set" method, which does the same as the "clone", it exists
986only for compatibility.
987
988=item to_tz
989
990You can use "to_tz" to create a new object, which means the same time as
991the base object, but in the different timezone.
992
993Note that $date->clone( tz => 'Iceland') and $date->to_tz('Iceland') is not
994the same! Cloning a new object with setting timezone will preserve the
995time information (hour, minute, second, etc.), but transfer the time into
996other timezone, while to_tz usually change these values based on the
997difference between the source and the destination timezone.
998
999=item Operations with Class::Date::Rel
1000
1001The Class::Date::Rel object consists of a month part and a day part. Most
1002people only use the "day" part of it. If you use both part, then you can get
1003these parts with the "sec_part" and "mon_part" method. If you use "sec",
1004"month", etc. methods or if you use this object in a mathematical context,
1005then this object is converted to one number, which is interpreted as second.
1006The conversion is based on a 30.436 days month. Don't use it too often,
1007because it is confusing...
1008
1009If you use Class::Date::Rel in an expression with other Class::Date or
1010Class::Date::Rel objects, then it does what is expected:
1011
1012  date('2001-11-12')+'1M' will be '2001-12-12'
1013
1014and
1015
1016  date('1996-02-11')+'2M' will be '1996-04-11'
1017
1018=back
1019
1020=head2 Accessing data from a Class::Date and Class::Date::Rel object
1021
1022You can use the methods methods described at the top of the document
1023if you want to access parts of the data
1024which is stored in a Class::Date and Class::Date::Rel object.
1025
1026=head2 Error handling
1027
1028If a date object became invalid, then the object will be reblessed to
1029Class::Date::Invalid. This object is false in boolean environment, so you can
1030test the date validity like this:
1031
1032  $a = date($input_date);
1033  if ($a) { # valid date
1034      ...
1035  } else { # invalid date
1036      if ($a->error == E_INVALID) { ... }
1037      print $a->errstr;
1038  }
1039
1040Note even the date is invalid, the expression "defined $a" always returns
1041true, so the following is wrong:
1042
1043  $a = date($input_date);
1044  if (defined $a) ... # WRONG!!!!
1045
1046You can test the error by getting the $date->error value. You might import
1047the ":errors" tag:
1048
1049  use Class::Date qw(:errors);
1050
1051Possible error values are:
1052
1053=over 4
1054
1055=item E_OK
1056
1057No errors.
1058
1059=item E_INVALID
1060
1061Invalid date. It is set when some of the parts of the date are invalid, and
1062Time::Local functions cannot convert them to a valid date.
1063
1064=item E_RANGE
1065
1066This error is set, when parts of the date are valid, but the whole date is
1067not valid, e.g. 2001-02-31. When the $Class::Date::RANGE_CHECK is not set, then
1068these date values are automatically converted to a valid date: 2001-03-03,
1069but the $date->error value are set to E_RANGE. If $Class::Date::RANGE_CHECK
1070is set, then a date "2001-02-31" became invalid date.
1071
1072=item E_UNPARSABLE
1073
1074This error is set, when the constructor cannot be created from a scalar, e.g:
1075
1076  $a = date("4kd sdlsdf lwekrmk");
1077
1078=item E_UNDEFINED
1079
1080This error is set, when you want to create a date object from an undefined
1081value:
1082
1083  $a = Class::Date->new(undef);
1084
1085Note, that localdate(undef) will create a valid object, because it calls
1086$Class::Date(time).
1087
1088=back
1089
1090You can get the error in string form by calling the "errstr" method.
1091
1092=head1 DST_ADJUST
1093
1094$DST_ADJUST is an important configuration option.
1095
1096If it is set to true (default), then the module adjusts the date and time
1097when the operation switches the border of DST. With this setting, you are
1098ignoring the effect of DST.
1099
1100When $DST_ADJUST is set to false, then no adjustment is done, the
1101calculation will be based on the exact time difference.
1102
1103You will see the difference through an example:
1104
1105  $Class::Date::DST_ADJUST=1;
1106
1107  print date("2000-10-29", "CET") + "1D";
1108  # This will print 2000-10-30 00:00:00
1109
1110  print date("2001-03-24 23:00:00", "CET") + "1D";
1111  # This will be 2001-03-25 23:00:00
1112
1113  print date("2001-03-25", "CET") + "1D";
1114  # This will be 2001-03-26 00:00:00
1115
1116
1117  $Class::Date::DST_ADJUST=0;
1118
1119  print date("2000-10-29", "CET") + "1D";
1120  # This will print 2000-10-29 23:00:00
1121
1122  print date("2001-03-24 23:00:00", "CET") + "1D";
1123  # This will be 2001-03-26 00:00:00
1124
1125=head1 MONTHS AND YEARS
1126
1127If you add or subtract "months" and "years" to a date, you may get wrong
1128dates, e.g when you add one month to 2001-01-31, you expect to get
11292001-02-31, but this date is invalid and converted to 2001-03-03. Thats' why
1130
1131  date("2001-01-31") + '1M' - '1M' != "2001-01-31"
1132
1133This problem can occur only with months and years, because others can
1134easily be converted to seconds.
1135
1136=head1 MONTH_BORDER_ADJUST
1137
1138$MONTH_BORDER_ADJUST variable is used to switch on or off the
1139month-adjust feature. This is used only when someone adds months or years to
1140a date and then the resulted date became invalid. An example: adding one
1141month to "2001-01-31" will result "2001-02-31", and this is an invalid date.
1142
1143When $MONTH_BORDER_ADJUST is false, this result simply normalized, and
1144becomes "2001-03-03". This is the default behaviour.
1145
1146When $MONTH_BORDER_ADJUST is true, this result becomes "2001-02-28". So when
1147the date overflows, then it returns the last day insted.
1148
1149Both settings keep the time information.
1150
1151=head1 TIMEZONE SUPPORT
1152
1153Since 1.0.11, Class::Date handle timezones natively on most platforms (see
1154the BUGS AND LIMITATIONS section for more info).
1155
1156When the module is loaded, then it determines the local base timezone by
1157calling the Class::Date::local_timezone() function, and stores these values
1158into two variables, these are: $Class::Date::LOCAL_TIMEZONE and
1159$Class::Date::DEFAULT_TIMEZONE. The first value is used, when you call the
1160"localdate" function, the second value is used, when you call the "date"
1161function and you don't specify the timezone. There is
1162a $Class::Date::GMT_TIMEZONE function also, which is used by the "gmdate"
1163function, this is set to 'GMT'.
1164
1165You can query the timezone of a date object by calling the $date->tz
1166method. Note this value returns the timezone as you specify, so if you
1167create the object with an unknown timezone, you will get this back. If you
1168want to query the effective timezone, you can call the $date->tzdst method.
1169This method returns only valid timezones, but it is not necessarily the
1170timezone which can be used to create a new object. For example
1171$date->tzdst can return 'CEST', which is not a valid base timezone, because
1172it contains daylight savings information also. On Linux systems, you can
1173see the possible base timezones in the /usr/share/zoneinfo directory.
1174
1175In Class::Date 1.1.6, a new environment variable is introduced:
1176$Class::Date::NOTZ_TIMEZONE. This variable stores the local timezone, which
1177is used, when the TZ environment variable is not set. It is introduced,
1178because there are some systems, which cannot handle the queried timezone
1179well. For example the local timezone is CST, it is returned by the tzname()
1180perl function, but when I set the TZ environment variable to CST, it
1181works like it would be GMT.  The workaround is NOTZ_TIMEZONE: if a date
1182object has a timezone, which is the same as NOTZ_TIMEZONE, then the TZ
1183variable will be removed before each calculation. In normal case, it would
1184be the same as setting TZ to $NOTZ_TIMEZONE, but some systems don't like
1185it, so I decided to introduce this variable. The
1186$Class::Date::NOTZ_TIMEZONE variable is set in the initialization of the
1187module by removing the TZ variable from the environment and querying the
1188tzname variable.
1189
1190=head1 INTERNALS
1191
1192This module uses operator overloading very heavily. I've found it quite stable,
1193but I am afraid of it a bit.
1194
1195A Class::Date object is an array reference.
1196
1197A Class::Date::Rel object is an array reference, which contains month and
1198second information. I need to store it as an array ref, because array and month
1199values cannot be converted into seconds, because of our super calendar.
1200
1201You can add code references to the @Class::Date::NEW_FROM_SCALAR and
1202@Class::Date::Rel::NEW_FROM_SCALAR. These arrays are iterated through when a
1203scalar-format date must be parsed. These arrays only have one or two values
1204at initialization. The parameters which the code references got are the same
1205as the "new" method of each class. In this way, you can personalize the date
1206parses as you want.
1207
1208As of 0.90, the Class::Date has been rewritten. A lot of code and design
1209decision has been borrowed from Matt Sergeant's Time::Object, and there will
1210be some incompatibility with the previous public version (0.5). I tried to
1211keep compatibility methods in Class::Date. If you have problems regarding
1212this, please drop me an email with the description of the problem, and I will
1213set the compatibility back.
1214
1215Invalid dates are Class::Date::Invalid objects. Every method call on this
1216object and every operation with this object returns undef or 0.
1217
1218=head1 DEVELOPMENT FOCUS
1219
1220This module tries to be as full-featured as can be. It currently lacks
1221business-day calculation, which is planned to be implemented in the 1.0.x
1222series.
1223
1224I try to keep this module not to depend on other modules and I want this
1225module usable without a C compiler.
1226
1227Currently the module uses the POSIX localtime function very extensively.
1228This makes the date calculation a bit slow, but provides a rich interface,
1229which is not provided by any other module. When I tried to redesign the
1230internals to not depend on localtime, I failed, because there are no other
1231way to determine the daylight savings information.
1232
1233=head1 SPEED ISSUES
1234
1235There are two kind of adjustment in this module, DST_ADJUST and
1236MONTH_BORDER_ADJUST. Both of them makes the "+" and "-" operations slower. If
1237you don't need them, switch them off to achieve faster calculations.
1238
1239In general, if you really need fast date and datetime calculation, don't use
1240this module. As you see in the previous section, the focus of development is
1241not the speed in 1.0.  For fast date and datetime calculations, use
1242Date::Calc module instead.
1243
1244=head1 THREAD SAFETY and MOD_PERL
1245
1246This module is NOT thread-safe, since it uses C library functions, which
1247are not thread-safe. Using this module in a multi-threaded environment can
1248cause timezones to be messed up. I did not put any warning about it, you
1249have to make sure that you understand this!
1250
1251Under some circumstances in a mod_perl environment, you require the Env::C
1252module to set the TZ variable properly before calling the time functions. I
1253added the -EnvC import option to automatically load this module if it is
1254not loaded already. Please read the mod_perl documentation about the
1255environment variables and mod_perl to get the idea why it is required
1256sometimes:
1257
1258  http://perl.apache.org/docs/2.0/user/troubleshooting/troubleshooting.html#C_Libraries_Don_t_See_C__ENV__Entries_Set_by_Perl_Code
1259
1260You are sure have this problem if the $Class::Date::NOTZ_TIMEZONE variable
1261is set to 'UTC', althought you are sure that your timezone is not that. Try
1262-EnvC in this case, but make sure that you are not using it in a
1263multi-threaded environment!
1264
1265=head1 OTHER BUGS AND LIMITATIONS
1266
1267=over 4
1268
1269=item *
1270
1271Not all date/time values can be expressed in all timezones. For example:
1272
1273  print date("2010-10-03 02:00:00", "Australia/Sydney")
1274  # it will print 2010-10-03 03:00:00
1275
1276No matter how hard you try you, you are not going to be able to express the
1277time in the example in that timezone. If you don't need the timezone
1278information and you want to make sure that the calculations are always
1279correct, please use GMT as a timezone (the 'gmdate' function can be a
1280shortcut for it). In this case, you might also consider turning off
1281DST_ADJUST to speed up the calculation.
1282
1283=item *
1284
1285I cannot manage to get the timezone code working properly on ActivePerl
12865.8.0 on win XP and earlier versions possibly have this problem also. If
1287you have a system like this, then you will have only two timezones, the
1288local and the GMT. Every timezone, which is not equal to
1289$Class::Date::GMT_TIMEZONE is assumed to be local. This seems to be caused
1290by the win32 implementation of timezone routines. I don't really know how
1291to make this thing working, so I gave up this issue. If anyone know a
1292working solution, then I will integrate it into Class::Date, but until
1293then, the timezone support will not be available for these platforms.
1294
1295=item *
1296
1297Perl 5.8.0 and earlier versions has a bug in the strftime code on some
1298operating systems (for example Linux), which is timezone related. I
1299recommend using the strftime, which is provided with Class::Date, so don't
1300try to use the module without the compiled part. The module will not work
1301with a buggy strftime - the test is hardcoded into the beginning of the
1302code. If you anyway want to use the module, remove the hardcoded "die" from
1303the module, but do it for your own risk.
1304
1305=item *
1306
1307This module uses the POSIX functions for date and
1308time calculations, so it is not working for dates beyond 2038 and before 1902.
1309
1310I don't know what systems support dates in 1902-1970 range, it may not work on
1311your system. I know it works on the Linux glibc system with perl 5.6.1
1312and 5.7.2. I know it does not work with perl 5.005_03 (it may be the bug of
1313the Time::Local module). Please report if you know any system where it does
1314_not_ work with perl 5.6.1 or later.
1315
1316I hope that someone will fix this with new time_t in libc. If you really need
1317dates over 2038 and before 1902, you need to completely rewrite this module or
1318use Date::Calc or other date modules.
1319
1320=item *
1321
1322This module uses Time::Local, and when it croaks, Class::Date returns
1323"Invalid date or time" error message. Time::Local is different in the 5.005
1324and 5.6.x (and even 5.7.x) version of perl, so the following code will
1325return different results:
1326
1327  $a = date("2006-11-11")->clone(year => -1);
1328
1329In perl 5.6.1, it returns an invalid date with error message "Invali date or
1330time", in perl 5.005 it returns an invalid date with range check error. Both
1331are false if you use them in boolean context though, only the error message
1332is different, but don't rely on the error message in this case. It however
1333works in the same way if you change other fields than "year" to an invalid
1334field.
1335
1336=back
1337
1338=head1 SUPPORT
1339
1340Class::Date is free software. IT COMES WITHOUT WARRANTY OF ANY KIND.
1341
1342If you have questions, you can send questions directly to me:
1343
1344  dlux@dlux.hu
1345
1346=head1 WIN32 notes
1347
1348You can get a binary win32 version of Class::Date from Chris Winters' .ppd
1349repository with the following commands:
1350
1351For people using PPM2:
1352
1353  c:\> ppm
1354  PPM> set repository oi http://openinteract.sourceforge.net/ppmpackages/
1355  PPM> set save
1356  PPM> install Class-Date
1357
1358For people using PPM3:
1359
1360  c:\> ppm
1361  PPM> repository http://openinteract.sourceforge.net/ppmpackages/
1362  PPM> install Class-Date
1363
1364The first steps in PPM only needs to be done at the first time. Next time
1365you just run the 'install'.
1366
1367=head1 COPYRIGHT
1368
1369Copyright (c) 2001 Szabó, Balázs (dLux)
1370
1371All rights reserved. This program is free software; you can redistribute it
1372and/or modify it under the same terms as Perl itself.
1373
1374Portions Copyright (c) Matt Sergeant
1375
1376=head1 CREDITS
1377
1378  - Matt Sergeant <matt@sergeant.org>
1379    (Lots of code are borrowed from the Time::Object module)
1380  - Tatsuhiko Miyagawa <miyagawa@cpan.org> (bugfixes)
1381  - Stas Bekman <stas@stason.org> (suggestions, bugfix)
1382  - Chris Winters <chris@cwinters.com> (win32 .ppd version)
1383  - Benoit Beausejour <bbeausej@pobox.com>
1384    (Parts of the timezone code is borrowed from his Date::Handler module)
1385
1386=head1 SEE ALSO
1387
1388perl(1).
1389Date::Calc(3pm).
1390Time::Object(3pm).
1391Date::Handler(3pm).
1392
1393=head1 AUTHORS
1394
1395=over 4
1396
1397=item *
1398
1399dLux (Szabó, Balázs) <dlux@dlux.hu>
1400
1401=item *
1402
1403Gabor Szabo <szabgab@gmail.com>
1404
1405=item *
1406
1407Yanick Champoux <yanick@cpan.org>
1408
1409=back
1410
1411=head1 COPYRIGHT AND LICENSE
1412
1413This software is copyright (c) 2018, 2014, 2010, 2003 by Balázs Szabó.
1414
1415This is free software; you can redistribute it and/or modify it under
1416the same terms as the Perl 5 programming language system itself.
1417
1418=cut
1419