Date-Tie

 view release on metacpan or  search on metacpan

lib/Date/Tie.pm  view on Meta::CPAN

# FIRSTKEY added to support recommended assignment order: set timezone, then epoch and fractional seconds
#   tie my %b, 'Date::Tie', tz => $d{tz}, epoch => $d{epoch}, frac => $d{frac};

sub FIRSTKEY {
    my ($self) = @_;
    return 'tz';
}

sub NEXTKEY {
    my ($self, $lastkey) = @_;
    return 'epoch' if $lastkey eq 'tz';
    return 'frac'  if $lastkey eq 'epoch';
    return undef;
}

# This is for debugging only !
# sub iso { my $self = shift; return $self->{year} . '-' . $self->{month} . '-' . $self->{day} . " $self->{weekyear}-W$self->{week}-$self->{weekday}"; }
# sub debug { return; my $self = shift; return join(':',%{$self}); }

1;

__END__

=head1 NAME

Date::Tie - ISO dates made easy

=head1 SYNOPSIS

    use Date::Tie;

    tie my %date, 'Date::Tie', year => 2001, month => 11, day => 9;
    $date{year}++;
    $date{month} += 12;    # 2003-11-09

    # you can also use OO syntax
    my $date = Date::Tie->new( year => 2001, month => 11, day => 9 );
    $date->{year}++;
    $date->{month} += 12;  # 2003-11-09

    $date{weekday} = 0;    # sunday at the start of this week
    $date{weekday} = 7;    # sunday at the end of this week
    $date{weekday} = 14;   # sunday next week 

    $date{tz} = '-0300';   # change timezone
    $date{tzhour}++;       # increment timezone

    # "next month's last day"
    $date{month}+=2;
    $date{day} = 0;        # this is actually a "-1" since days start in "1"

    # copy a date with timezone
    tie my %newdate, 'Date::Tie', tz => $date{tz}, epoch => $date{epoch};
    or
    tie my %newdate, 'Date::Tie', %date;

=head1 DESCRIPTION

Date::Tie is an attempt to simplify date operations syntax.

It works with calendar dates (year-month-day), 
ordinal dates (year-day), week dates (year-week-day),
times (hour:minute:second), decimal fractions (decimal hours,
decimal minutes and decimal seconds), and time-zones. 

Whenever a Date::Tie hash key receives a new value, it will change 
the other keys following the ISO date rules. 
For example: 

     print $a{hour}, ":", $a{minute};     #  '00:59'
     $a{minute}++;
     print $a{hour}, ":", $a{minute};     #  '01:00'

=head1 DEFAULT VALUE

The default value of a new hash is the current value of I<gmtime()>, 
with timezone C<+0000> and with fractional seconds set to zero.

=head1 HASH KEYS

Date::Tie manages a hash containing the keys: 

I<year>, I<month>, I<day>, I<hour>, I<minute>, I<second>,
I<yearday>, I<week>, I<weekday>, I<weekyear>, 
I<epoch>, I<utc_epoch>,
I<tz>, I<tzhour>, I<tzminute>,
I<frac_hour>, I<frac_minute>, I<frac_second>, I<frac_epoch>,
I<frac>. 

All keys can be read and written to.

=over 4

=item I<year>, I<month>, I<day> or I<monthday>, I<hour>, I<minute>, I<second>

These keys are just what they say. 

You can use B<I<monthday>> instead of I<day> if you want to make it clear
it is not a I<yearday> (ordinal calendar) or a I<weekday> (week calendar). 

=item I<yearday>, I<week>, I<weekday>, I<weekyear>

B<I<yearday>> is the day number in the year.

B<I<weekday>> is the day number in the week. I<weekday> C<1> is monday.

B<I<week>> is the week number in the year.

B<I<weekyear>> is the year number, when referring to a week of a year.
It is often I<not equal> to I<year>. 
Changing I<weekyear> will leave you with the same week and weekday, 
while changing I<year> will leave you with the same month and monthday.

=item I<epoch>

B<I<epoch>> is an internal notation and is not a part of the ISO8601
standard. 

This value is system-dependent, and it might overflow
for dates outside the years 1970-2038. 

B<I<epoch>> is the local epoch. That is, time 
C<20020101T000000+0300> is the same epoch as 
C<20020101T000000+0600>.

=item I<utc_epoch>

The system epoch in UTC time, that is, in timezone C<+0000>.

See also the C<epoch> key.

=item I<tz>, I<tzhour>, I<tzminute>

B<I<tz>> is the timezone as hundreds, like in C<-0030>. 
It is I<not always> the same as the expression
S<C<$date{tzhour} . $date{tzminute}>>, which in this case would be C<-00-30>.

Changing timezone (any of I<tz>, I<tzhour>, or I<tzminute>) changes I<epoch>.

=item I<frac_hour>, I<frac_minute>, I<frac_second>, I<frac_epoch>

These keys are used for fractional decimal notation:

    $d{hour}   = 13;
    $d{minute} = 30;                 # 0.5 hour
    $d{second} = 00;       
    print $d{frac_hour};             # '13.5'

    $d{frac_minute} = 17.3;
    print "$d{minute}:$d{second}";   # '17:18'
    $d{frac_minute} -= 0.2;
    print "$d{minute}:$d{second}";   # '17:06'

    $d{epoch} = 1234567;
    $d{frac}  = 0.7654321;
    print $d{frac_epoch};            # '1234567.7654321'

=item I<frac>



( run in 0.470 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )