Improved working time calculation.

This commit is contained in:
Martin Edenhofer 2013-04-15 23:32:39 +02:00
parent 254c2ff46a
commit 970cf59283
3 changed files with 155 additions and 8 deletions

View file

@ -15,19 +15,48 @@ module BusinessTime
def after(time) def after(time)
after_time = Time.roll_forward(time) after_time = Time.roll_forward(time)
# Step through the hours, skipping over non-business hours # Step through the minutes, skipping over non-business minutes
@minutes.times do days = @minutes / 60 / 24
after_time = after_time + 1.minute hours = ( @minutes - ( days * 60 * 24 ) ) / 60
minutes = @minutes - ( (days * 60 * 24 ) + (hours * 60) )
if @minutes > 60 * 12
end
local_sec = @minutes * 60
loop = true
while (loop == true) do
a = after_time
if local_sec >= 60 * 60
after_time = after_time + 1.hour
else
after_time = after_time + 1.minute
end
# Ignore minutes before opening and after closing # Ignore minutes before opening and after closing
if (after_time > Time.end_of_workday(after_time)) if (after_time > Time.end_of_workday(after_time))
after_time = after_time + off_minutes after_time = after_time + off_minutes
if local_sec < 60 * 60
after_time = after_time - 60
else
after_time = after_time - 60 * 60
end
next
end end
# Ignore weekends and holidays # Ignore weekends and holidays
while !Time.workday?(after_time) while !Time.workday?(after_time)
after_time = after_time + 1.day after_time = Time.beginning_of_workday(after_time + 1.day)
a = after_time
end end
diff = after_time - a
local_sec = local_sec - diff
if local_sec <= 0
loop = false
next
end
end end
after_time after_time
end end

View file

@ -25,14 +25,20 @@ module TimeCalculation
end end
def self.business_time_diff(start_time, end_time) def self.business_time_diff(start_time, end_time)
start_time = Time.parse( start_time.to_s + 'UTC' ) if start_time.class == String
end_time = Time.parse( end_time.to_s + 'UTC' ) start_time = Time.parse( start_time.to_s + 'UTC' )
end
if end_time.class == String
end_time = Time.parse( end_time.to_s + 'UTC' )
end
diff = start_time.business_time_until( end_time ) / 60 diff = start_time.business_time_until( end_time ) / 60
diff.round diff.round
end end
def self.dest_time(start_time, diff_in_min) def self.dest_time(start_time, diff_in_min)
start_time = Time.parse( start_time.to_s + ' UTC' ) if start_time.class == String
start_time = Time.parse( start_time.to_s + ' UTC' )
end
dest_time = diff_in_min.round.business_minute.after( start_time ) dest_time = diff_in_min.round.business_minute.after( start_time )
return dest_time return dest_time
end end

View file

@ -129,11 +129,123 @@ class WorkingTimeTest < ActiveSupport::TestCase
'end_of_workday' => '6:00 pm', 'end_of_workday' => '6:00 pm',
}, },
}, },
# test 3
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-18 18:00:00',
:diff => 1200,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 4
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-19 08:30:00',
:diff => 1230,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 5
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-21 18:00:00',
:diff => 3000,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 6
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-24 08:05:00',
:diff => 3005,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 7
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-31 08:05:00',
:diff => 6005,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 8
{
:start => '2012-12-17 08:00:00',
:dest_time => '2012-12-31 13:30:00',
:diff => 6330,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
# test 9
{
:start => '2013-04-12 21:20:15',
:dest_time => '2013-04-15 10:00:00',
:diff => 120,
:config => {
'Mon' => true,
'Tue' => true,
'Wed' => true,
'Thu' => true,
'Fri' => true,
'beginning_of_workday' => '8:00 am',
'end_of_workday' => '6:00 pm',
},
},
] ]
tests.each { |test| tests.each { |test|
TimeCalculation.config( test[:config] ) TimeCalculation.config( test[:config] )
dest_time = TimeCalculation.dest_time( test[:start] + ' UTC', test[:diff] ) dest_time = TimeCalculation.dest_time( test[:start] + ' UTC', test[:diff] )
assert_equal( dest_time.gmtime, Time.parse( test[:dest_time] + ' UTC' ), 'dest time' ) assert_equal( dest_time.gmtime, Time.parse( test[:dest_time] + ' UTC' ), "dest time - #{test[:dest_time].to_s}" )
} }
end end