in reply to perl logic to calculate total time taken excluding non working hours
Hello sachinhere,
I put together an example using Date::Manip module as a possible complete solution to your problem.
Sample of solution bellow:
#!/usr/bin/perl use strict; use warnings; use Date::Manip; use Data::Dumper; use feature 'say'; my $dateStart = "Jan 29 2018 4:59pm"; my $dateEnd = "Jan 30 2018 08:01am"; my $business = DateCalc($dateStart, $dateEnd, "business"); my $businessTime = Delta_Format($business, 0, "Time in %hv hours, %mv minutes, %sv seconds"); say $businessTime; my $nonBusiness = DateCalc($dateStart, $dateEnd, "exact"); my $nonBusinessTime = Delta_Format($nonBusiness, 0, "Time in %hv hours, %mv minutes, %sv seconds"); say $nonBusinessTime; my @businessArray = split(/:/, $business); my @nonBusinessArray = split(/:/, $nonBusiness); my @totalArray; foreach my $i ( 0 .. $#businessArray ) { push @totalArray, $nonBusinessArray[$i] - $businessArray[$i]; } ### For Output Viewing Purposes ### my @dateFormat = ("years", "months", "weeks", "days", "hours", "minutes", "seconds"); my %totalHash; @totalHash{@dateFormat} = @totalArray; # print Dumper \%totalHash; my $deltaStr = join(':', @totalArray); my $str = Delta_Format($deltaStr,"Total %hv hours, %mv minutes, %sv se +conds"); say $str; __END__ $ perl test.pl Time in 0 hours, 2 minutes, 0 seconds Time in 15 hours, 2 minutes, 0 seconds Total 15 hours, 0 minutes, 0 seconds
What you need to notice here is, for the module the default working (business) hours are between 08:00 am - 5:00 pm (1 hour lunch in between). If these times do not fit your criteria (e.g. you prefer start at 08:30 am and end 5:30 pm) you can modify them, read more on how to do it here BUSINESS CONFIGURATION VARIABLES.
Regarding the Adding the Mode options e.g. "business" explanation. This parameter that you can add on the DateCalc function is $mode. This parameter when you do date calculations can take 6 different options. Sample from the documentation:
exact : an exact, non-business calculation semi : a semi-exact, non-business calculation approx : an approximate, non-business calculation business : an exact, business calculation bsemi : a semi-exact, business calculation bapprox : an approximate, business calculation
Each $mode has a different ability and output. For example $mode exact will return only hours and seconds and not days/weeks/months/years. If you are wondering why you can read here EXACT, SEMI-EXACT, AND APPROXIMATE DATE/DELTA CALCULATIONS.
The calculations that you can do through this module are almost infinite, I tried to add the minimum possible modifications to resolve your problem. I would encourage you to read as much as possible the documentation to understand the output and how you can adjust it on your requirements (timezone, working hours, holidays etc...etc...).
Update: Maybe I miss understood your initial question. I was under the impression that you want to calculate the time between non working hours. If this is what you want the code above should work, in case you do not want to do that and you are only interested in calculating the time between working hours see bellow:
#!/usr/bin/perl use strict; use warnings; use Date::Manip; use feature 'say'; my $dateStart = "Jan 29 2018 4:59pm"; my $dateEnd = "Jan 30 2018 08:01am"; my $business = DateCalc($dateStart, $dateEnd, "business"); my $businessTime = Delta_Format($business, 0, "Time in %hv hours, %mv minutes, %sv seconds"); say $businessTime; __END__ $ perl test.pl Time in 0 hours, 2 minutes, 0 seconds
Update 2: Another "similar question" was raised some time ago see Calculating Number Of Pay Periods. On this thread apart from calculating the time between two days during business hours you can also calculate between time-zones see Re: Calculating Number Of Pay Periods (UPDATED).
I hope this helps, BR
|
---|