package Handy::Dandy::TimeTools;
use strict;
use vars qw( $AUTOLOAD $ATL $SEC $MIN $HOUR $DAY $WEEK $YEAR );
use constant UTC_OFFSET => -5;
use Exporter;
use OOorNO qw( :all );
$Handy::Dandy::TimeTools::VERSION = 0.1_5; # 9/23/02, 3:05 pm
@Handy::Dandy::TimeTools::ISA = qw( Exporter OOorNO );
@Handy::Dandy::TimeTools::EXPORT_OK = qw
(
UTC_OFFSET
stamp to_seconds convert_time seconds_since
second minute hour month year dayofweek dayofyear
minutestart hourstart daystart weekstart monthstart yearstart
);
%Handy::Dandy::TimeTools::EXPORT_TAGS =
(
'all' => [ @Handy::Dandy::TimeTools::EXPORT_OK ]
);
=pod
AUTHOR
Tommy Butler <tommy @ atrixnet.com>
phone: (817)-468-7716
6711 Forest Park Dr
Arlington, TX
76001-8403
COPYRIGHT Tommy Butler. All rights reserved
LISCENCE This software is free, use/distribute under the GNU GPL.
BUGS TO Tommy Butler <perlmod @ atrixnet.com>
=cut
$SEC = qr/^SEC/; $MIN = qr/^MIN/; $HOUR = qr/^HOUR/;
$DAY = qr/^DAY/; $WEEK = qr/^WEEK/; $YEAR = qr/^YEAR/;
# --------------------------------------------------------
# Constructor
# --------------------------------------------------------
sub new { bless({}, shift(@_)); }
# --------------------------------------------------------
# Handy::Dandy::TimeTools::stamp()
# --------------------------------------------------------
{
my($months) =
[
'January', 'February', 'March', 'April',
'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December',
];
my($days) =
[
'Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'
];
sub stamp {
my($opts) = shave_opts(\@_);
my($argtime,$offset) = myargs(@_);
$argtime ||= time unless Handy::Dandy->isint($argtime);
$offset ||= UTC_OFFSET unless Handy::Dandy->isint($offset);
$argtime += ($offset * 3600);
my($sec,$min,$h24,$date,$mon,$year,$wday,$yday) = gmtime($argtime);
my($hour) = $h24;
$hour = $h24 - 12 if ($h24 > 12); $hour = 12 if ($hour == 0);
my($AMPM) = ($h24 >= 12) ? 'pm' : 'am';
goto DEFAULT if ($opts->{'--short'} or !scalar(keys(%$opts)));
# -June-15-2002-16.22.43
return
(
sprintf(
q[-%s-%u-%u-%u.%02u.%02u],
$months->[$mon], $date, $year + 1900,
$h24, $min, $sec
)
) if ($opts->{'--file'} || $opts->{'--filename'});
# 5/15/02
return
(
sprintf(
q[%s/%s/%2s],
$mon + 1, $date, substr($year + 1900, 2)
)
) if $opts->{'--mdy'};
# Saturday, June 15, 2002, 4:22 pm
return
(
sprintf(
q[%s, %s %u, %u, %s:%02u %s],
$days->[$wday], $months->[$mon], $date, $year + 1900,
$hour, $min, $AMPM
)
) if ($opts->{'--formal'} || $opts->{'--long'});
# Sat, 15 Jun 2002 16.22.43 GMT
return
(
sprintf(
q[%s, %0.2f %s:%02u:%02u GMT],
substr($days->[$wday],0,3), $date, substr($months->[$mon],0,3),
$year + 1900, $h24, $min, $sec
)
) if $opts->{'--ISO'};
# Sat 5/15/02 16:22:43
return
(
sprintf(
q[%s %s/%s/%2s %s:%02u:%02u],
substr($days->[$wday],0,3), $mon + 1, $date,
substr($year + 1900, 2), $h24, $min, $sec
)
) if $opts->{'--succinct'};
# 4:22 pm
return
(
sprintf(
q[%s:%02u %s],
$hour, $min, $AMPM
)
) if $opts->{'--hm'};
# 4:22:43 pm
return
(
sprintf(
q[%s:%02u:%02u %s],
$hour, $min, $sec, $AMPM
)
) if $opts->{'--hms'};
# 16:22:43
return
(
sprintf(
q[%s:%02u:%02u],
$h24, $min, $sec
)
) if $opts->{'--24hms'};
# MOVING TO IF-ELSIF-ELSE SEQUENCE NOW...
if ($opts->{'--dayofmonth'}) {
# (number of the date) 1 - [28-31]
return($date);
}
elsif ($opts->{'--dayofweek'}) {
# (number for day of the week) 1 - 7
return($wday+1) if $opts->{'--num'};
# (name of the day) Sunday - Saturday
return($days->[$wday]);
}
elsif ($opts->{'--dayofyear'}) {
# (number for day of the year) 1 - 365 (non-leap)
return($yday);
}
elsif ($opts->{'--month'}) {
# (number of the month) 1 - 12
return($mon+1) if $opts->{'--num'};
# (name of the month) January - December
return($months->[$mon]);
}
elsif ($opts->{'--year'}) {
# (year number) 2002
return($year + 1900);
}
elsif ($opts->{'--shortyear'}) {
# (abbreviated year number)
return(substr($year + 1900, 2));
}
elsif ($opts->{'--minute'}) {
# (number of the minute) 0 - 59
return($min);
}
elsif ( $opts->{'--hour'}) {
# (number of the hour) 0 - 24
return($h24);
}
elsif ($opts->{'--second'}) {
# (number of the second) 0 - 59
return($sec);
}
else {
DEFAULT:
# 5/15/02, 4:22 pm
return
(
sprintf(
q[%s/%u/%2s, %s:%02u %s],
$mon + 1, $date, substr($year + 1900, 2),
$hour, $min, $AMPM
)
);
}
'';
}
}
# --------------------------------------------------------
# Handy::Dandy::TimeTools::to_seconds()
# --------------------------------------------------------
sub to_seconds {
my($unit) = ${\myargs(@_)} || return(undef);
my($amt) = 0;
($amt,$unit) = split(/ /,$unit); $unit = uc($unit);
return(0) unless Handy::Dandy::isnum($amt);
if ($unit =~ /$SEC/) { return($amt); }
elsif ($unit =~ /$MIN/) { return($amt * 60); }
elsif ($unit =~ /$HOUR/) { return($amt * 3600); }
elsif ($unit =~ /$DAY/) { return($amt * 86400); }
elsif ($unit =~ /$WEEK/) { return($amt * 604800); }
elsif ($unit =~ /$YEAR/) { return($amt * 31536000); }
-1;
}
# --------------------------------------------------------
# Handy::Dandy::TimeTools::seconds_since()
# --------------------------------------------------------
sub seconds_since {
my($opts) = shave_opts(\@_);
my($h,$m,$s) =
(
stamp('--hour','--num'),
stamp('--minute'),
stamp('--second')
);
$h = to_seconds(qq[$h hours]); $m = to_seconds(qq[$m minutes]);
if ($opts->{'--minutestart'}) { return($s); }
elsif ($opts->{'--hourstart'}) { return($m + $s); }
elsif ($opts->{'--daystart'}) { return($h + $m + $s); }
elsif ($opts->{'--weekstart'}) {
return($h + $m + $s + to_seconds(stamp('--dayofweek','--num') - 1 . q[ days]));
}
elsif ($opts->{'--monthstart'}) {
return($h + $m + $s + to_seconds(stamp('--dayofmonth') - 1 . q[ days]));
}
elsif ($opts->{'--yearstart'}) {
return($h + $m + $s + to_seconds(stamp('--dayofyear') . q[ days]) - 3600);
}
undef;
}
# Handy::Dandy::TimeTools::-------------------------------
# minutestart(), hourstart(), daystart(),
# weekstart(), monthstart(), yearstart()
# --------------------------------------------------------
sub minutestart { time - seconds_since(q[--minutestart]); }
sub hourstart { time - seconds_since(q[--hourstart]); }
sub daystart { time - seconds_since(q[--daystart]); }
sub weekstart { time - seconds_since(q[--weekstart]); }
sub monthstart { time - seconds_since(q[--monthstart]); }
sub yearstart { time - seconds_since(q[--yearstart]); }
# --------------------------------------------------------
# Handy::Dandy::TimeTools::AUTOLOAD()
# --------------------------------------------------------
sub AUTOLOAD {
my($sub) = $AUTOLOAD; $sub =~ s/^.*\:\://o;
if (ref($ATL) ne 'HASH') { $ATL = eval($ATL); }
if (ref(eval(qq[\$sub])) eq 'CODE') { goto &$sub; }
unless ($ATL->{ $sub }) {
die(qq[BAD AUTOLOAD. Can't do $sub(). Don't know what it is.]);
}
eval($ATL->{ $sub }); CORE::delete($ATL->{ $sub });
goto &$sub;
}
# --------------------------------------------------------
# Handy::Dandy::TimeTools::DESTROY()
# --------------------------------------------------------
sub DESTROY {}
INIT { $ATL = <<'___AUTOLOADED___'; }
{
'convert_time' => <<'__SUB__',
# --------------------------------------------------------
# Handy::Dandy::TimeTools::convert_time()
# --------------------------------------------------------
sub convert_time {
# syntax: $dandy->convert_time($int, q[days to hours])
my($amt, $cmd) = myargs(@_);
return(undef) unless Handy::Dandy::isnum($amt);
my(@specs) = split(/ /,uc($cmd));
my($from) = $specs[0];
my($to) = $specs[-1];
# FROM conversions
# (note: conversion FROM seconds TO unit x is implicit)
if ($from =~ /$MIN/) { $amt *= 60; }
elsif ($from =~ /$HOUR/) { $amt *= 3600; }
elsif ($from =~ /$DAY/) { $amt *= 86400; }
elsif ($from =~ /$WEEK/) { $amt *= 604800; }
elsif ($from =~ /$YEAR/) { $amt *= 31536000; }
# TO conversions
if ($to =~ /$MIN/) { return($amt / 60); }
elsif ($to =~ /$HOUR/) { return($amt / 3600); }
elsif ($to =~ /$DAY/) { return($amt / 86400); }
elsif ($to =~ /$WEEK/) { return($amt / 604800); }
elsif ($to =~ /$YEAR/) { return($amt / 31536000); }
return($amt);
}
__SUB__
# Handy::Dandy::TimeTools::-------------------------------
# second(), minute(), hour(), month(), year()
# dayofmonth(), dayofweek(), dayofyear()
# --------------------------------------------------------
'second' => <<'__SUB__',
sub second { stamp('--second'); }
__SUB__
'minute' => <<'__SUB__',
sub minute { stamp('--minute'); }
__SUB__
'hour' => <<'__SUB__',
sub hour { stamp('--hour'); }
__SUB__
'month' => <<'__SUB__',
sub month { stamp('--month','--num'); }
__SUB__
'year' => <<'__SUB__',
sub year { stamp('--year'); }
__SUB__
'dayofmonth' => <<'__SUB__',
sub dayofmonth { stamp('--dayofmonth','--num'); }
__SUB__
'dayofweek' => <<'__SUB__',
sub dayofweek { stamp('--dayofweek','--num'); }
__SUB__
'dayofyear' => <<'__SUB__',
sub dayofyear { stamp('--dayofyear'); }
__SUB__
}
___AUTOLOADED___
# --------------------------------------------------------
# end Handy::Dandy::TimeTools Class, return true on import
# --------------------------------------------------------
1;
=FOR REFERENCE
TIME CONVERSION REFERENCE TABLE
1 minute = 60 seconds
1 hour = 60 minutes
60 minutes = 3600 seconds
1 day = 24 hours
24 hours = 1440 minutes
1440 minutes = 86400 seconds
1 week = 7 days
1 week = 7.0347222 days (leap sec)
7.0347222 days = 168.8333333 hours (leap sec)
7 days = 604800 seconds
168.8333333 hours = 10130 minutes
10130 minutes = 604800 seconds
1 year = 365.2425116 days
365.2425116 days = 8765.8202778 hours
8765.8202778 hours = 525949.2166667 minutes
525949.2166667 minutes = 31556953 seconds
(
1 => [31, 31, 0],
2 => [28, 59, 31],
3 => [31, 90, 59],
4 => [30,120, 90],
5 => [31,151,120],
6 => [30,181,151],
7 => [31,212,181],
8 => [31,243,212],
9 => [30,273,243],
10 => [31,304,273],
11 => [30,334,304],
12 => [31,365,334],
);
for each item in the above data structure:
month => [(days within), (total days after), (total days before)]
=cut