Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: determining work hours between 2 dates

by kosie99 (Acolyte)
on Jul 26, 2006 at 10:28 UTC ( [id://563745]=note: print w/replies, xml ) Need Help??


in reply to determining work hours between 2 dates

Ok, fixed a bug, new script:
#!/usr/bin/perl # # CORRECT VERSION # use strict; use Time::Local; use Text::CSV; my $debug = 0; my $infile; while (@ARGV) { $_ = shift; /(.*\.csv$)/ && do {$infile = $1; next}; /^-d/ && do {$debug++; next}; } my %holidays = { "20060101" => 1, "20060317" => 1, "20060414" => 1, "20060417" => 1, "20060501" => 1, "20060605" => 1, "20060807" => 1, "20061030" => 1, "20061225" => 1, "20061226" => 1 }; open(IF,"$infile") || die "cannot open $infile\n"; while (my $line = <IF>) { $line =~ /^FAULT/ && next; my $csv = Text::CSV->new; $csv->parse($line) || die "Could not parse line:$line:$csv->error_in +put"; my ($ref,$a,$b,$c,$d,$start,$end) = $csv->fields; my $datepair = "$start" . "|" . "$end"; my $work_seconds = &get_work_seconds($datepair); print "$ref,$work_seconds\n"; } close(IF); ######################## sub get_work_seconds { my $datepair = shift; print "$datepair\n" if $debug; $datepair =~ /(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})\|(\d +{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})/; my ($y1,$m1,$d1,$h1,$min1,$s1) = ($1,$2,$3,$4,$5,$6); my ($y2,$m2,$d2,$h2,$min2,$s2) = ($7,$8,$9,$10,$11,$12); my $yyyymmdd1 = $y1 . $m1 . $d1; my $yyyymmdd2 = $y2 . $m2 . $d2; my $same_day = 0; if ($yyyymmdd1 eq $yyyymmdd2) { $same_day = 1; } my ($day_start1,$day_end1) = &day_ctime_range($yyyymmdd1); my ($day_start2,$day_end2) = &day_ctime_range($yyyymmdd2); my $date1 = timelocal($s1,$min1,$h1,$d1,$m1-1,$y1); my $date2 = timelocal($s2,$min2,$h2,$d2,$m2-1,$y2); if ($date1 < $day_start1) { $date1 = $day_start1; } if ($date1 > $day_end1) { $date1 = $day_end1; } if ($date2 < $day_start2) { $date2 = $day_start2; } if ($date2 > $day_end2) { $date2 = $day_end2; } my $date1_secs; my $date2_secs; if ($same_day) { if ($date1 > $date2) { print "ERR: $date1 > $date2\n"; } $date1_secs = $date2 - $date1; $date2_secs = 0; } else { $date1_secs = $day_end1 - $date1; $date2_secs = $date2 - $day_start2; } if (&non_workday($date1)) { $date1_secs = 0; } if (&non_workday($date2)) { $date2_secs = 0; } print "date1_secs=$date1_secs\n" if $debug; print "date2_secs=$date2_secs\n" if $debug; my $days = 0; $date1 += 86400; while ($date1 < $day_start2) { my $nwday = &non_workday($date1); if ($nwday == 0) { $days++; } $date1 += 86400; } print "NUMBER_DAYS=$days\n" if $debug; my $seconds = ((8.5 * 60 * 60) * $days) + ($date2_secs + $date1_secs +); print ("((8.5 * 60 * 60) * $days) + $date2_secs + $date1_secs = $sec +onds\n") if $debug; return $seconds; } ######################## sub day_ctime_range { #for a given YYMMDD return start and end ctime my $today = shift(); $today =~ /^(\d\d\d\d)(\d\d)(\d\d)$/; my ($yyyy,$mm,$dd) = ($1,$2,$3); my $start = timelocal(0,30,8,$dd,$mm-1,$yyyy-1900); my $end = timelocal(0,0,17,$dd,$mm-1,$yyyy-1900); return ($start,$end); } ######################################## sub non_workday { my ($some_time) = shift; my $non_workday = 0; # check if a day is a holiday my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = loc +altime($some_time); my $yyyy = $year+1900; my $mm = $mon+1; my $yyyymmdd= sprintf ("%4d%02d%02d", $yyyy, $mm, $mday); #check list of holidays from table $non_workday = 1 if exists $holidays{$yyyymmdd}; if ($wday == 0 || $wday == 6) { $non_workday = 1; } return ($non_workday); } ########################################

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://563745]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-25 07:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found