Date::Tie - ISO dates made easy
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;
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'
The default value of a new hash is the current value of gmtime(), with timezone +0000 and with fractional seconds set to zero.
+0000
Date::Tie manages a hash containing the keys:
year, month, day, hour, minute, second, yearday, week, weekday, weekyear, epoch, utc_epoch, tz, tzhour, tzminute, frac_hour, frac_minute, frac_second, frac_epoch, frac.
All keys can be read and written to.
These keys are just what they say.
You can use monthday instead of day if you want to make it clear it is not a yearday (ordinal calendar) or a weekday (week calendar).
yearday is the day number in the year.
weekday is the day number in the week. weekday 1 is monday.
1
week is the week number in the year.
weekyear is the year number, when referring to a week of a year. It is often not equal to year. Changing weekyear will leave you with the same week and weekday, while changing year will leave you with the same month and monthday.
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.
epoch is the local epoch. That is, time 20020101T000000+0300 is the same epoch as 20020101T000000+0600.
20020101T000000+0300
20020101T000000+0600
The system epoch in UTC time, that is, in timezone +0000.
See also the epoch key.
epoch
tz is the timezone as hundreds, like in -0030. It is not always the same as the expression $date{tzhour} . $date{tzminute}, which in this case would be -00-30.
-0030
$date{tzhour} . $date{tzminute}
-00-30
Changing timezone (any of tz, tzhour, or tzminute) changes 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'
Fractional seconds. A value bigger or equal to 0 and less than 1 second.
$d{frac} = 0.5; print $d{frac}; # '.5' $d{frac} = 0; print $d{frac}; # '.0'
Setting frac does not change second or epoch, unless it overflows:
$d{second} = 6; print $d{second}; # '06' $d{frac} = 1.5; print $d{second}; # '07' - frac overflow print $d{frac}; # '.5'
To obtain the fractional second or epoch:
print "$d{second}$d{frac}"; # '07.5' - concatenation print $d{second} + $d{frac}; # '7.5' - addition print $d{epoch} + $d{frac}; # '45673455.5' - fractional epoch
See also: frac_epoch and frac_second.
Day of year starts with 001.
001
Day of week starts with 1 and is a monday.
Week starts with 01 and is the first week of the year that has a thursday. Week 01 often begins in the previous year.
01
Since Date::Tie is based on gmtime() and timegm(), it is expected to work only on years between 1970 and 2038 (this is system-dependent).
Date::Tie
gmtime()
timegm()
Reading time zone -0030 with $date{tzhour} . $date{tzminute} gives -00-30. Use tz to get -0030.
The order of setting hash elements is important, since changing the timezone will change the hour.
These are some ways to make a copy of %d:
%d
# copy all fields # hash %d MUST be tied do Date::Tie, if you are using timezones tie my %b, 'Date::Tie', %d; # set timezone, then epoch, ignoring fractional seconds tie my %b, 'Date::Tie', tz => $d{tz}, epoch => $d{epoch}; # set timezone, then epoch and fractional seconds tie my %b, 'Date::Tie', tz => $d{tz}, epoch => $d{epoch}, frac => $d{frac}; # set timezone, then fractional epoch tie my %b, 'Date::Tie', tz => $d{tz}, frac_epoch => $d{frac_epoch};
In OO style you can use new to make a copy:
new
# make a copy of object my $b = $d->new; # make a copy of object, then set the copy to next month ($b = $d->new)->{month}++; # make a copy of object, then set the copy to month 3 $b = $d->new(month => 3);
If you change month, then day will be adjusted to fit that month:
$date = (month=>10, day=>31); $date{month}++; # month=>11, day=>30
If you need to know whether a hash is tied to Date::Tie use perl function tied()
DateTime and http://datetime.perl.org
http://datetime.perl.org
Date::Calc, Date::Manip, Class::Date, and many other good date and time modules!
Date::Tie depends on Tie::Hash, Time::Local and POSIX.
dmoz section on ISO8601 at http://dmoz.org/Science/Reference/Standards/Individual_Standards/ISO_8601/
http://dmoz.org/Science/Reference/Standards/Individual_Standards/ISO_8601/
Markus Kuhn wrote a summary of ISO8601 International Standard Date and Time Notation, that can be found at http://www.cl.cam.ac.uk/~mgk25/iso-time.html
http://www.cl.cam.ac.uk/~mgk25/iso-time.html
Flávio Soibelmann Glock (fglock@gmail.com)
Original idea based on a mail by dLux.
Eduardo M. Cavalcanti, Henrique Pantarotto and Jean contributed bugfixes.
Dan Wright created the utc_epoch key.
utc_epoch
1 POD Error
The following errors were encountered while parsing the POD:
Non-ASCII character seen before =encoding in 'Flávio'. Assuming CP1252
To install Date::Tie, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Date::Tie
CPAN shell
perl -MCPAN -e shell install Date::Tie
For more information on module installation, please visit the detailed CPAN module installation guide.