Code:
$
$
$ cat -n timediff.pl
1 #perl -w
2 use Date::Calc qw(:all);
3 if ($#ARGV != 1) {
4 print "Usage: perl timediff.pl <START_DATE> <END_DATE>\n";
5 print "Both dates in \"mm/dd/yyyy hh24:mi:ss\" format\n";
6 exit;
7 }
8 # @sd = ($y,$mm,$d,$h,$mi,$s); same as @ed
9 @sd = (split/[ :\/]/,$ARGV[0])[2,0,1,3,4,5];
10 $sd[5] eq "" and $sd[5]=0;
11 $sdow = Day_of_Week(@sd[0,1,2]);
12 printf ("START DATE => %s, %d/%d/%d %02d:%02d:%02d\n",
13 Day_of_Week_Abbreviation($sdow),@sd[1,2,0,3,4,5]);
14 @ed = (split/[ :\/]/,$ARGV[1])[2,0,1,3,4,5];
15 $ed[5] eq "" and $ed[5]=0;
16 $edow = Day_of_Week(@ed[0,1,2]);
17 printf ("END DATE => %s, %d/%d/%d %02d:%02d:%02d\n",
18 Day_of_Week_Abbreviation($edow),@ed[1,2,0,3,4,5]);
19 # === Dates must be in chronological order ===
20 if (Date_to_Time(@sd) > Date_to_Time(@ed)) {
21 print "The dates are not in chronological order. Abnormal Exit.\n";
22 exit;
23 }
24 # === Case 1 : Both dates lie within the weekend ===
25 $ddelta = Delta_Days(@sd[0,1,2], @ed[0,1,2]);
26 # Dow = 1 for Monday; Dow = 7 for Sunday
27 if ($sdow > 5 and $edow > 5 and $ddelta <= 1) {
28 print "Both dates lie within the weekend. Elapsed time will not be calculated.\n";
29 exit;
30 }
31 # === Case 2 : The dates do not span more than one day ===
32 if ($ddelta == 0) {
33 ($dd,$dh,$dm,$ds) = Delta_DHMS(@sd, @ed);
34 printf("Elapsed time = %d days %d hours %d minutes %d seconds\n", $dd,$dh,$dm,$ds);
35 exit;
36 }
37 # === Case 3 : The dates span multiple days; we'll loop through them and exclude weekends ===
38 for ($i = 0; $i <= $ddelta; $i++) {
39 @d = Add_Delta_Days(@sd[0,1,2],$i);
40 $ddow = Day_of_Week(@d[0,1,2]);
41 if ($i == 0 and $ddow <= 5) {
42 @next = Add_Delta_Days(@sd[0,1,2],1);
43 ($dd,$dh,$dm,$ds) = Delta_DHMS(@sd, @next,0,0,0);
44 } elsif ($i == $ddelta and $ddow <= 5) {
45 @y = Delta_DHMS(@ed[0,1,2],0,0,0, @ed);
46 $dd += $y[0]; $dh += $y[1];
47 $dm += $y[2]; $ds += $y[3];
48 } elsif ($ddow <= 5) {
49 $ds += 24*60*60;
50 }
51 }
52 @normalized = Normalize_DHMS($dd,$dh,$dm,$ds);
53 printf("Elapsed time, excluding weekends = %d days %d hours %d minutes %d seconds\n", @normalized);
$
$
$ # Incorrect invocation
$ perl timediff.pl
Usage: perl timediff.pl <START_DATE> <END_DATE>
Both dates in "mm/dd/yyyy hh24:mi:ss" format
$
$ # Dates in reverse order
$ perl timediff.pl "1/2/2010 10:11:12" "1/1/2010 15:16:17"
START DATE => Sat, 1/2/2010 10:11:12
END DATE => Fri, 1/1/2010 15:16:17
The dates are not in chronological order. Abnormal Exit.
$
$ # Dates lying within the weekend
$ perl timediff.pl "1/2/2010 0:0:0" "1/3/2010 23:59:59"
START DATE => Sat, 1/2/2010 00:00:00
END DATE => Sun, 1/3/2010 23:59:59
Both dates lie within the weekend. Elapsed time will not be calculated.
$
$ # And the rest of the testcases...
$ perl timediff.pl "1/1/2010 0:0:0" "1/1/2010 23:59:59"
START DATE => Fri, 1/1/2010 00:00:00
END DATE => Fri, 1/1/2010 23:59:59
Elapsed time = 0 days 23 hours 59 minutes 59 seconds
$
$ perl timediff.pl "1/1/2010 0:0:0" "1/2/2010 0:0:0"
START DATE => Fri, 1/1/2010 00:00:00
END DATE => Sat, 1/2/2010 00:00:00
Elapsed time, excluding weekends = 1 days 0 hours 0 minutes 0 seconds
$
$
$ # From a weekend date to a non-weekend date
$ perl timediff.pl "1/2/2010 11:12:13" "1/5/2010 14:15:16"
START DATE => Sat, 1/2/2010 11:12:13
END DATE => Tue, 1/5/2010 14:15:16
Elapsed time, excluding weekends = 1 days 14 hours 15 minutes 16 seconds
$
$
$ # From a non-weekend date to a weekend date
$ perl timediff.pl "1/1/2010 11:12:13" "1/3/2010 14:15:16"
START DATE => Fri, 1/1/2010 11:12:13
END DATE => Sun, 1/3/2010 14:15:16
Elapsed time, excluding weekends = 0 days 12 hours 47 minutes 47 seconds
$
$
$ # Encompassing one weekend
$ perl timediff.pl "1/1/2010 11:12:13" "1/4/2010 14:15:16"
START DATE => Fri, 1/1/2010 11:12:13
END DATE => Mon, 1/4/2010 14:15:16
Elapsed time, excluding weekends = 1 days 3 hours 3 minutes 3 seconds
$
$
$ # Encompassing more than one weekend
$ perl timediff.pl "1/1/2010 11:12:13" "1/14/2010 14:15:16"
START DATE => Fri, 1/1/2010 11:12:13
END DATE => Thu, 1/14/2010 14:15:16
Elapsed time, excluding weekends = 9 days 3 hours 3 minutes 3 seconds
$
$
$ # An entire year
$ perl timediff.pl "1/1/2010 0:0:0" "12/31/2010 23:59:59"
START DATE => Fri, 1/1/2010 00:00:00
END DATE => Fri, 12/31/2010 23:59:59
Elapsed time, excluding weekends = 260 days 23 hours 59 minutes 59 seconds
$
$
$