1b39c5158Smillertpackage Time::Seconds;
2b39c5158Smillertuse strict;
3b39c5158Smillert
4*56d68f1eSafresh1our $VERSION = '1.3401';
5e5157e49Safresh1
6e5157e49Safresh1use Exporter 5.57 'import';
7b39c5158Smillert
8b8851fccSafresh1our @EXPORT = qw(
9b39c5158Smillert    ONE_MINUTE
10b39c5158Smillert    ONE_HOUR
11b39c5158Smillert    ONE_DAY
12b39c5158Smillert    ONE_WEEK
13b39c5158Smillert    ONE_MONTH
14b39c5158Smillert    ONE_YEAR
15b39c5158Smillert    ONE_FINANCIAL_MONTH
16b39c5158Smillert    LEAP_YEAR
17b39c5158Smillert    NON_LEAP_YEAR
18b39c5158Smillert);
19b39c5158Smillert
20b8851fccSafresh1our @EXPORT_OK = qw(cs_sec cs_mon);
21b39c5158Smillert
22b8851fccSafresh1use constant {
23b8851fccSafresh1    ONE_MINUTE => 60,
24b8851fccSafresh1    ONE_HOUR => 3_600,
25b8851fccSafresh1    ONE_DAY => 86_400,
26b8851fccSafresh1    ONE_WEEK => 604_800,
27b8851fccSafresh1    ONE_MONTH => 2_629_744, # ONE_YEAR / 12
28b8851fccSafresh1    ONE_YEAR => 31_556_930, # 365.24225 days
29b8851fccSafresh1    ONE_FINANCIAL_MONTH => 2_592_000, # 30 days
30b8851fccSafresh1    LEAP_YEAR => 31_622_400, # 366 * ONE_DAY
31b8851fccSafresh1    NON_LEAP_YEAR => 31_536_000, # 365 * ONE_DAY
32b39c5158Smillert    # hacks to make Time::Piece compile once again
33b8851fccSafresh1    cs_sec => 0,
34b8851fccSafresh1    cs_mon => 1,
35b8851fccSafresh1};
36b39c5158Smillert
37b39c5158Smillertuse overload
38b39c5158Smillert    'fallback' => 'undef',
39b39c5158Smillert    '0+' => \&seconds,
40b39c5158Smillert    '""' => \&seconds,
41b39c5158Smillert    '<=>' => \&compare,
42b39c5158Smillert    '+' => \&add,
43b39c5158Smillert    '-' => \&subtract,
44b39c5158Smillert    '-=' => \&subtract_from,
45b39c5158Smillert    '+=' => \&add_to,
46b39c5158Smillert    '=' => \&copy;
47b39c5158Smillert
48b39c5158Smillertsub new {
49b39c5158Smillert    my $class = shift;
50b39c5158Smillert    my ($val) = @_;
51b39c5158Smillert    $val = 0 unless defined $val;
52b39c5158Smillert    bless \$val, $class;
53b39c5158Smillert}
54b39c5158Smillert
55b39c5158Smillertsub _get_ovlvals {
56b39c5158Smillert    my ($lhs, $rhs, $reverse) = @_;
57b39c5158Smillert    $lhs = $lhs->seconds;
58b39c5158Smillert
59b39c5158Smillert    if (UNIVERSAL::isa($rhs, 'Time::Seconds')) {
60b39c5158Smillert        $rhs = $rhs->seconds;
61b39c5158Smillert    }
62b39c5158Smillert    elsif (ref($rhs)) {
63b39c5158Smillert        die "Can't use non Seconds object in operator overload";
64b39c5158Smillert    }
65b39c5158Smillert
66b39c5158Smillert    if ($reverse) {
67b39c5158Smillert        return $rhs, $lhs;
68b39c5158Smillert    }
69b39c5158Smillert
70b39c5158Smillert    return $lhs, $rhs;
71b39c5158Smillert}
72b39c5158Smillert
73b39c5158Smillertsub compare {
74b39c5158Smillert    my ($lhs, $rhs) = _get_ovlvals(@_);
75b39c5158Smillert    return $lhs <=> $rhs;
76b39c5158Smillert}
77b39c5158Smillert
78b39c5158Smillertsub add {
79b39c5158Smillert    my ($lhs, $rhs) = _get_ovlvals(@_);
80b39c5158Smillert    return Time::Seconds->new($lhs + $rhs);
81b39c5158Smillert}
82b39c5158Smillert
83b39c5158Smillertsub add_to {
84b39c5158Smillert    my $lhs = shift;
85b39c5158Smillert    my $rhs = shift;
86b39c5158Smillert    $rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds');
87b39c5158Smillert    $$lhs += $rhs;
88b39c5158Smillert    return $lhs;
89b39c5158Smillert}
90b39c5158Smillert
91b39c5158Smillertsub subtract {
92b39c5158Smillert    my ($lhs, $rhs) = _get_ovlvals(@_);
93b39c5158Smillert    return Time::Seconds->new($lhs - $rhs);
94b39c5158Smillert}
95b39c5158Smillert
96b39c5158Smillertsub subtract_from {
97b39c5158Smillert    my $lhs = shift;
98b39c5158Smillert    my $rhs = shift;
99b39c5158Smillert    $rhs = $rhs->seconds if UNIVERSAL::isa($rhs, 'Time::Seconds');
100b39c5158Smillert    $$lhs -= $rhs;
101b39c5158Smillert    return $lhs;
102b39c5158Smillert}
103b39c5158Smillert
104b39c5158Smillertsub copy {
105b39c5158Smillert	Time::Seconds->new(${$_[0]});
106b39c5158Smillert}
107b39c5158Smillert
108b39c5158Smillertsub seconds {
109b39c5158Smillert    my $s = shift;
110b39c5158Smillert    return $$s;
111b39c5158Smillert}
112b39c5158Smillert
113b39c5158Smillertsub minutes {
114b39c5158Smillert    my $s = shift;
115b39c5158Smillert    return $$s / 60;
116b39c5158Smillert}
117b39c5158Smillert
118b39c5158Smillertsub hours {
119b39c5158Smillert    my $s = shift;
120b39c5158Smillert    $s->minutes / 60;
121b39c5158Smillert}
122b39c5158Smillert
123b39c5158Smillertsub days {
124b39c5158Smillert    my $s = shift;
125b39c5158Smillert    $s->hours / 24;
126b39c5158Smillert}
127b39c5158Smillert
128b39c5158Smillertsub weeks {
129b39c5158Smillert    my $s = shift;
130b39c5158Smillert    $s->days / 7;
131b39c5158Smillert}
132b39c5158Smillert
133b39c5158Smillertsub months {
134b39c5158Smillert    my $s = shift;
135b39c5158Smillert    $s->days / 30.4368541;
136b39c5158Smillert}
137b39c5158Smillert
138b39c5158Smillertsub financial_months {
139b39c5158Smillert    my $s = shift;
140b39c5158Smillert    $s->days / 30;
141b39c5158Smillert}
142b39c5158Smillert
143b39c5158Smillertsub years {
144b39c5158Smillert    my $s = shift;
145b39c5158Smillert    $s->days / 365.24225;
146b39c5158Smillert}
147b39c5158Smillert
1489f11ffb7Safresh1sub _counted_objects {
1499f11ffb7Safresh1    my ($n, $counted) = @_;
1509f11ffb7Safresh1    my $number = sprintf("%d", $n); # does a "floor"
1519f11ffb7Safresh1    $counted .= 's' if 1 != $number;
1529f11ffb7Safresh1    return ($number, $counted);
1539f11ffb7Safresh1}
1549f11ffb7Safresh1
15548950c12Ssthensub pretty {
15648950c12Ssthen    my $s = shift;
15748950c12Ssthen    my $str = "";
15848950c12Ssthen    if ($s < 0) {
15948950c12Ssthen        $s = -$s;
16048950c12Ssthen        $str = "minus ";
16148950c12Ssthen    }
16248950c12Ssthen    if ($s >= ONE_MINUTE) {
16348950c12Ssthen        if ($s >= ONE_HOUR) {
16448950c12Ssthen            if ($s >= ONE_DAY) {
1659f11ffb7Safresh1                my ($days, $sd) = _counted_objects($s->days, "day");
1669f11ffb7Safresh1                $str .= "$days $sd, ";
16748950c12Ssthen                $s -= ($days * ONE_DAY);
16848950c12Ssthen            }
1699f11ffb7Safresh1            my ($hours, $sh) = _counted_objects($s->hours, "hour");
1709f11ffb7Safresh1            $str .= "$hours $sh, ";
17148950c12Ssthen            $s -= ($hours * ONE_HOUR);
17248950c12Ssthen        }
1739f11ffb7Safresh1        my ($mins, $sm) = _counted_objects($s->minutes, "minute");
1749f11ffb7Safresh1        $str .= "$mins $sm, ";
17548950c12Ssthen        $s -= ($mins * ONE_MINUTE);
17648950c12Ssthen    }
1779f11ffb7Safresh1    $str .= join " ", _counted_objects($s->seconds, "second");
17848950c12Ssthen    return $str;
17948950c12Ssthen}
18048950c12Ssthen
181b39c5158Smillert1;
182b39c5158Smillert__END__
183b39c5158Smillert
184e5157e49Safresh1=encoding utf8
185e5157e49Safresh1
186b39c5158Smillert=head1 NAME
187b39c5158Smillert
188b39c5158SmillertTime::Seconds - a simple API to convert seconds to other date values
189b39c5158Smillert
190b39c5158Smillert=head1 SYNOPSIS
191b39c5158Smillert
192b39c5158Smillert    use Time::Piece;
193b39c5158Smillert    use Time::Seconds;
194b39c5158Smillert
195b39c5158Smillert    my $t = localtime;
196b39c5158Smillert    $t += ONE_DAY;
197b39c5158Smillert
198b39c5158Smillert    my $t2 = localtime;
199b39c5158Smillert    my $s = $t - $t2;
200b39c5158Smillert
201b39c5158Smillert    print "Difference is: ", $s->days, "\n";
202b39c5158Smillert
203b39c5158Smillert=head1 DESCRIPTION
204b39c5158Smillert
205b39c5158SmillertThis module is part of the Time::Piece distribution. It allows the user
206b39c5158Smillertto find out the number of minutes, hours, days, weeks or years in a given
207b39c5158Smillertnumber of seconds. It is returned by Time::Piece when you delta two
208b39c5158SmillertTime::Piece objects.
209b39c5158Smillert
210b39c5158SmillertTime::Seconds also exports the following constants:
211b39c5158Smillert
212b39c5158Smillert    ONE_DAY
213b39c5158Smillert    ONE_WEEK
214b39c5158Smillert    ONE_HOUR
215b39c5158Smillert    ONE_MINUTE
216b39c5158Smillert    ONE_MONTH
217b39c5158Smillert    ONE_YEAR
218b39c5158Smillert    ONE_FINANCIAL_MONTH
219b39c5158Smillert    LEAP_YEAR
220b39c5158Smillert    NON_LEAP_YEAR
221b39c5158Smillert
222b39c5158SmillertSince perl does not (yet?) support constant objects, these constants are in
223b39c5158Smillertseconds only, so you cannot, for example, do this: C<print ONE_WEEK-E<gt>minutes;>
224b39c5158Smillert
225b39c5158Smillert=head1 METHODS
226b39c5158Smillert
227b39c5158SmillertThe following methods are available:
228b39c5158Smillert
229b39c5158Smillert    my $val = Time::Seconds->new(SECONDS)
230b39c5158Smillert    $val->seconds;
231b39c5158Smillert    $val->minutes;
232b39c5158Smillert    $val->hours;
233b39c5158Smillert    $val->days;
234b39c5158Smillert    $val->weeks;
235b39c5158Smillert    $val->months;
236b39c5158Smillert    $val->financial_months; # 30 days
237b39c5158Smillert    $val->years;
23848950c12Ssthen    $val->pretty; # gives English representation of the delta
23948950c12Ssthen
24048950c12SsthenThe usual arithmetic (+,-,+=,-=) is also available on the objects.
241b39c5158Smillert
242b39c5158SmillertThe methods make the assumption that there are 24 hours in a day, 7 days in
243b39c5158Smillerta week, 365.24225 days in a year and 12 months in a year.
244b39c5158Smillert(from The Calendar FAQ at http://www.tondering.dk/claus/calendar.html)
245b39c5158Smillert
246b39c5158Smillert=head1 AUTHOR
247b39c5158Smillert
248b39c5158SmillertMatt Sergeant, matt@sergeant.org
249b39c5158Smillert
250b39c5158SmillertTobias Brox, tobiasb@tobiasb.funcom.com
251b39c5158Smillert
252e5157e49Safresh1Balázs Szabó (dLux), dlux@kapu.hu
253b39c5158Smillert
254e5157e49Safresh1=head1 COPYRIGHT AND LICENSE
255b39c5158Smillert
256e5157e49Safresh1Copyright 2001, Larry Wall.
257e5157e49Safresh1
258e5157e49Safresh1This module is free software, you may distribute it under the same terms
259e5157e49Safresh1as Perl.
260b39c5158Smillert
261b39c5158Smillert=head1 Bugs
262b39c5158Smillert
263b39c5158SmillertCurrently the methods aren't as efficient as they could be, for reasons of
264b39c5158Smillertclarity. This is probably a bad idea.
265b39c5158Smillert
266b39c5158Smillert=cut
267