Removed /usr/local from CDPATH
[clearscm.git] / lib / TimeUtils.pm
1 =pod
2
3 =head1 NAME $RCSfile: TimeUtils.pm,v $
4
5 Common time utilities
6
7 =head1 VERSION
8
9 =over
10
11 =item Author
12
13 Andrew DeFaria <Andrew@ClearSCM.com>
14
15 =item Revision
16
17 $Revision: 1.13 $
18
19 =item Created
20
21 Fri Mar 12 10:17:44 PST 2004
22
23 =item Modified
24
25 $Date: 2012/11/13 23:34:13 $
26
27 =back
28
29 =head1 SYNOPSIS
30
31 This module seeks to handle time and duration entities in a simple
32 manner. Given a time(3) structure we have routines to format out, in a
33 human readable form, a duration.
34
35  my $startTime = time;
36
37  # Do something that takes time...
38
39  # Display how long that took
40  display_duration $startTime;
41
42  # Displays how long that took into $log (See Logger.pm)
43  display_duration $startTime, $log;
44
45  # Get a date timestamp for today
46  my $yyyymmdd = format_yyyymmdd;
47
48  # Get a human readable duration between $startTime 
49  # and the current time
50  my $duration = howlong $startTime, time;
51
52 =head1 DESCRIPTION
53
54 This module exports a few time/duration related routines
55
56 =head1 ROUTINES
57
58 The following routines are exported:
59
60 =cut
61
62 package TimeUtils;
63
64 use strict;
65 use warnings;
66
67 use base "Exporter";
68 use File::Spec;
69
70 our @EXPORT = qw (
71   display_duration
72   format_yyyymmdd
73   howlong
74 );
75
76 use Display;
77 use Logger;
78
79 sub howlong ($;$) {
80   my ($start_time, $end_time) = @_;
81
82 =pod
83
84 =head2 howlong ($start_time, $end_time)
85
86 Returns a string that represents a human readable version of the
87 duration of time between $start_time and $end_time. For example, "1
88 hour, 10 minues and 5 seconds".
89
90 Parameters:
91
92 =for html <blockquote>
93
94 =over
95
96 =item $start_time
97
98 Time that represents the start time of the time period.
99
100 =item $end_time
101
102 Time that represents the end time of the time period. (Default;
103 Current time)
104
105 =back
106
107 =for html </blockquote>
108
109 Returns:
110
111 =for html <blockquote>
112
113 =over
114
115 =item $duration string
116
117 =back
118
119 =for html </blockquote>
120
121 =cut
122
123   $end_time ||= time;
124
125   return if $start_time > $end_time;
126
127   my $difference = $end_time - $start_time;
128
129   my $seconds_per_min  = 60;
130   my $seconds_per_hour = 60 * $seconds_per_min;
131   my $seconds_per_day  = $seconds_per_hour * 24;
132
133   my $days    = 0;
134   my $hours   = 0;
135   my $minutes = 0;
136   my $seconds = 0;
137
138   if ($difference > $seconds_per_day) {
139     $days       = int ($difference / $seconds_per_day);
140     $difference = $difference % $seconds_per_day;
141   } # if
142
143   if ($difference > $seconds_per_hour) {
144     $hours      = int ($difference / $seconds_per_hour);
145     $difference = $difference % $seconds_per_hour;
146   } # if
147
148   if ($difference > $seconds_per_min) {
149     $minutes    = int ($difference / $seconds_per_min);
150     $difference = $difference % $seconds_per_min;
151   } # if
152
153   $seconds = $difference;
154
155   my $day_str  = '';
156   my $hour_str = '';
157   my $min_str  = '';
158   my $sec_str  = '';
159   my $duration = '';
160
161   if ($days > 0) {
162     $day_str  = $days == 1 ? '1 day' : "$days days";
163     $duration = $day_str;
164   } # if
165
166   if ($hours > 0) {
167     $hour_str = $hours == 1 ? '1 hour' : "$hours hours";
168
169     if ($duration ne '') {
170       $duration .= ' ' . $hour_str;
171     } else {
172       $duration = $hour_str;
173     } # if
174   } # if
175
176   if ($minutes > 0) {
177     $min_str = $minutes == 1 ? '1 minute' : "$minutes minutes";
178
179     if ($duration ne '') {
180       $duration .= ' ' . $min_str;
181     } else {
182       $duration = $min_str;
183     } # if
184   } # if
185
186   if ($seconds > 0) {
187     $sec_str = $seconds == 1 ? '1 second' : "$seconds seconds";
188
189     if ($duration ne '') {
190       $duration .= ' ' . $sec_str;
191     } else {
192       $duration = $sec_str;
193     } # if
194   } # if
195
196   if ($duration eq '' and $seconds == 0) {
197     $duration = 'under 1 second';
198   } # if
199
200   return $duration;
201 } # howlong
202
203 sub display_duration ($;$) {
204   my ($start_time, $log) = @_;
205
206 =pod
207
208 =head2 display_duration ($start_time, $log)
209
210 Displays the duration between $start_time and now to STDOUT (or
211 optionally to log it to $log - See Logger)
212
213 Parameters:
214
215 =for html <blockquote>
216
217 =over
218
219 =item $start_time
220
221 Time that represents the start time of the time period.
222
223 =item $log
224
225 Log object to long durtion to.
226
227 =back
228
229 =for html </blockquote>
230
231 Returns:
232
233 =for html <blockquote>
234
235 =over
236
237 =item Nothing
238
239 =back
240
241 =for html </blockquote>
242
243 =cut
244
245   unless ($start_time) {
246     if ($log) {
247       $log->msg ('Finished in 0 seconds');
248     } else {
249       display 'Finished in 0 seconds';
250     } # if
251   } # unless
252
253   my $end_time = time;
254   my $duration = howlong $start_time, $end_time;
255
256   if ($log) {
257     $log->msg ("Finished in $duration");
258   } else {
259     display "Finished in $duration";
260   } # if
261
262   return;
263 } # display_duration
264
265 sub format_yyyymmdd ($) {
266   my ($time) = @_;
267
268 =pod
269
270 =head2 format_yyyymmdd ($time)
271
272 Quickly returns a YYYYMMDD format date for $time. If $time is not
273 specified then it returns today.
274
275 Parameters:
276
277 =for html <blockquote>
278
279 =over
280
281 =item $time
282
283 The $time to get the date from
284
285 =back
286
287 =for html </blockquote>
288
289 Returns:
290
291 =for html <blockquote>
292
293 =over
294
295 =item Date string in YYYYMMDD format for $time
296
297 =back
298
299 =for html </blockquote>
300
301 =cut
302
303   $time ||= time;
304
305   my ($sec, $min, $hour, $mday, $mon, $year) = localtime ($time);
306
307   $year += 1900;
308   $mon++;
309   $mon   = $mon  < 10 ? "0$mon"  : $mon;
310   $mday  = $mday < 10 ? "0$mday" : $mday;
311
312   return '$year$mon$mday';
313 } # format_yyyymmdd
314
315 1;
316
317 =head1 CONFIGURATION AND ENVIRONMENT
318
319 DEBUG: If set then $debug is set to this level.
320
321 VERBOSE: If set then $verbose is set to this level.
322
323 TRACE: If set then $trace is set to this level.
324
325 =head1 DEPENDENCIES
326
327 =head2 Perl Modules
328
329 L<File::Spec|File::Spec>
330
331 =head2 ClearSCM Perl Modules
332
333 =for html <p><a href='/php/scm_man.php?file=lib/Display.pm'>Display</a></p>
334
335 =for html <p><a href='/php/scm_man.php?file=lib/Logger.pm'>Logger</a></p>
336
337 =head1 INCOMPATABILITIES
338
339 None yet...
340
341 =head1 BUGS AND LIMITATIONS
342
343 There are no known bugs in this module.
344
345 Please report problems to Andrew DeFaria <Andrew@ClearSCM.com>.
346
347 =head1 LICENSE AND COPYRIGHT
348
349 This Perl Module is freely available; you can redistribute it and/or
350 modify it under the terms of the GNU General Public License as
351 published by the Free Software Foundation; either version 2 of the
352 License, or (at your option) any later version.
353
354 This Perl Module is distributed in the hope that it will be useful,
355 but WITHOUT ANY WARRANTY; without even the implied warranty of
356 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
357 General Public License (L<http://www.gnu.org/copyleft/gpl.html>) for more
358 details.
359
360 You should have received a copy of the GNU General Public License
361 along with this Perl Module; if not, write to the Free Software Foundation,
362 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
363 reserved.
364
365 =cut