1package Time::Seconds; 2use strict; 3use vars qw/@EXPORT @EXPORT_OK/; 4 5our $VERSION = '1.27'; 6 7use Exporter 5.57 'import'; 8 9@EXPORT = qw( 10 ONE_MINUTE 11 ONE_HOUR 12 ONE_DAY 13 ONE_WEEK 14 ONE_MONTH 15 ONE_REAL_MONTH 16 ONE_YEAR 17 ONE_REAL_YEAR 18 ONE_FINANCIAL_MONTH 19 LEAP_YEAR 20 NON_LEAP_YEAR 21); 22 23@EXPORT_OK = qw(cs_sec cs_mon); 24 25use constant ONE_MINUTE => 60; 26use constant ONE_HOUR => 3_600; 27use constant ONE_DAY => 86_400; 28use constant ONE_WEEK => 604_800; 29use constant ONE_MONTH => 2_629_744; # ONE_YEAR / 12 30use constant ONE_REAL_MONTH => '1M'; 31use constant ONE_YEAR => 31_556_930; # 365.24225 days 32use constant ONE_REAL_YEAR => '1Y'; 33use constant ONE_FINANCIAL_MONTH => 2_592_000; # 30 days 34use constant LEAP_YEAR => 31_622_400; # 366 * ONE_DAY 35use constant NON_LEAP_YEAR => 31_536_000; # 365 * ONE_DAY 36 37# hacks to make Time::Piece compile once again 38use constant cs_sec => 0; 39use constant cs_mon => 1; 40 41use overload 42 'fallback' => 'undef', 43 '0+' => \&seconds, 44 '""' => \&seconds, 45 '<=>' => \&compare, 46 '+' => \&add, 47 '-' => \&subtract, 48 '-=' => \&subtract_from, 49 '+=' => \&add_to, 50 '=' => \© 51 52sub new { 53 my $class = shift; 54 my ($val) = @_; 55 $val = 0 unless defined $val; 56 bless \$val, $class; 57} 58 59sub _get_ovlvals { 60 my ($lhs, $rhs, $reverse) = @_; 61 $lhs = $lhs->seconds; 62 63 if (UNIVERSAL::isa($rhs, 'Time::Seconds')) { 64 $rhs = $rhs->seconds; 65 } 66 elsif (ref($rhs)) { 67 die "Can't use non Seconds object in operator overload"; 68 } 69 70 if ($reverse) { 71 return $rhs, $lhs; 72 } 73 74 return $lhs, $rhs; 75} 76 77sub compare { 78 my ($lhs, $rhs) = _get_ovlvals(@_); 79 return $lhs <=> $rhs; 80} 81 82sub add { 83 my ($lhs, $rhs) = _get_ovlvals(@_); 84 return Time::Seconds->new($lhs + $rhs); 85} 86 87sub add_to { 88 my $lhs = shift; 89 my $rhs = shift; 90 $rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds'); 91 $$lhs += $rhs; 92 return $lhs; 93} 94 95sub subtract { 96 my ($lhs, $rhs) = _get_ovlvals(@_); 97 return Time::Seconds->new($lhs - $rhs); 98} 99 100sub subtract_from { 101 my $lhs = shift; 102 my $rhs = shift; 103 $rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds'); 104 $$lhs -= $rhs; 105 return $lhs; 106} 107 108sub copy { 109 Time::Seconds->new(${$_[0]}); 110} 111 112sub seconds { 113 my $s = shift; 114 return $$s; 115} 116 117sub minutes { 118 my $s = shift; 119 return $$s / 60; 120} 121 122sub hours { 123 my $s = shift; 124 $s->minutes / 60; 125} 126 127sub days { 128 my $s = shift; 129 $s->hours / 24; 130} 131 132sub weeks { 133 my $s = shift; 134 $s->days / 7; 135} 136 137sub months { 138 my $s = shift; 139 $s->days / 30.4368541; 140} 141 142sub financial_months { 143 my $s = shift; 144 $s->days / 30; 145} 146 147sub years { 148 my $s = shift; 149 $s->days / 365.24225; 150} 151 152sub pretty { 153 my $s = shift; 154 my $str = ""; 155 if ($s < 0) { 156 $s = -$s; 157 $str = "minus "; 158 } 159 if ($s >= ONE_MINUTE) { 160 if ($s >= ONE_HOUR) { 161 if ($s >= ONE_DAY) { 162 my $days = sprintf("%d", $s->days); # does a "floor" 163 $str = $days . " days, "; 164 $s -= ($days * ONE_DAY); 165 } 166 my $hours = sprintf("%d", $s->hours); 167 $str .= $hours . " hours, "; 168 $s -= ($hours * ONE_HOUR); 169 } 170 my $mins = sprintf("%d", $s->minutes); 171 $str .= $mins . " minutes, "; 172 $s -= ($mins * ONE_MINUTE); 173 } 174 $str .= $s->seconds . " seconds"; 175 return $str; 176} 177 1781; 179__END__ 180 181=encoding utf8 182 183=head1 NAME 184 185Time::Seconds - a simple API to convert seconds to other date values 186 187=head1 SYNOPSIS 188 189 use Time::Piece; 190 use Time::Seconds; 191 192 my $t = localtime; 193 $t += ONE_DAY; 194 195 my $t2 = localtime; 196 my $s = $t - $t2; 197 198 print "Difference is: ", $s->days, "\n"; 199 200=head1 DESCRIPTION 201 202This module is part of the Time::Piece distribution. It allows the user 203to find out the number of minutes, hours, days, weeks or years in a given 204number of seconds. It is returned by Time::Piece when you delta two 205Time::Piece objects. 206 207Time::Seconds also exports the following constants: 208 209 ONE_DAY 210 ONE_WEEK 211 ONE_HOUR 212 ONE_MINUTE 213 ONE_MONTH 214 ONE_YEAR 215 ONE_FINANCIAL_MONTH 216 LEAP_YEAR 217 NON_LEAP_YEAR 218 219Since perl does not (yet?) support constant objects, these constants are in 220seconds only, so you cannot, for example, do this: C<print ONE_WEEK-E<gt>minutes;> 221 222=head1 METHODS 223 224The following methods are available: 225 226 my $val = Time::Seconds->new(SECONDS) 227 $val->seconds; 228 $val->minutes; 229 $val->hours; 230 $val->days; 231 $val->weeks; 232 $val->months; 233 $val->financial_months; # 30 days 234 $val->years; 235 $val->pretty; # gives English representation of the delta 236 237The usual arithmetic (+,-,+=,-=) is also available on the objects. 238 239The methods make the assumption that there are 24 hours in a day, 7 days in 240a week, 365.24225 days in a year and 12 months in a year. 241(from The Calendar FAQ at http://www.tondering.dk/claus/calendar.html) 242 243=head1 AUTHOR 244 245Matt Sergeant, matt@sergeant.org 246 247Tobias Brox, tobiasb@tobiasb.funcom.com 248 249Balázs Szabó (dLux), dlux@kapu.hu 250 251=head1 COPYRIGHT AND LICENSE 252 253Copyright 2001, Larry Wall. 254 255This module is free software, you may distribute it under the same terms 256as Perl. 257 258=head1 Bugs 259 260Currently the methods aren't as efficient as they could be, for reasons of 261clarity. This is probably a bad idea. 262 263=cut 264