Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculations starting on non-business days #56

Closed
mwean opened this issue Apr 7, 2016 · 2 comments
Closed

Calculations starting on non-business days #56

mwean opened this issue Apr 7, 2016 · 2 comments

Comments

@mwean
Copy link

mwean commented Apr 7, 2016

I'm switching over to biz from business_time, and an issue I ran into was that calculations behave differently when the start time is not a business day. biz calculates a duration starting on Sunday as if it had started from Friday, whereas business_time treats it as if it started on Monday. For example:

schedule = Biz::Schedule.new do |config|
  config.hours = {
    mon: { '07:00' => '18:00' },
    tue: { '07:00' => '18:00' },
    wed: { '07:00' => '18:00' },
    thu: { '07:00' => '18:00' },
    fri: { '07:00' => '18:00' }
  }
end

friday = Time.new(2016, 4, 1, 12)
sunday = Time.new(2016, 4, 3, 12)

Biz::Calculation::ForDuration.days(schedule, 1).after(sunday)
#=> 2016-04-04 12:00:00 UTC

Biz::Calculation::ForDuration.days(schedule, 1).after(friday)
#=> 2016-04-04 12:00:00 UTC

And with business_time:

1.business_day.after(sunday)
#=> Tue, 05 Apr 2016 12:00:00 UTC +00:00

1.business_day.after(friday)
#=> Mon, 04 Apr 2016 12:00:00 UTC +00:00

I'm using time calculations for some compliance features, and I confirmed that the business_time behavior is correct. You can see their thinking in this comment. Would you be willing to change this behavior?

@craiglittle
Copy link
Collaborator

First, welcome, it's great to see more people using the gem!

Unlike seconds, minutes, or hours, day calculations are inherently ambiguous since they have to make an assumption about what "a day" means in countless contexts. Because of that, when I added the feature, my primary goal was to make the explanation of the logic as straightforward as possible, knowing that it's not going to satisfy all use cases:

Find the next day that contains business hours. Starting from the same minute on that day as the specified time, look forward (or back) to find the next moment in time that is in business hours.

The idea was to establish a clear, logical building block that would satisfy a solid number of the use cases out there while also enabling users to customize it as they see fit.

In short, I don't think changing the current day calculation logic is the right approach; however, you should be able to wrap it quite easily to get what you want.

Here's a rough sketch:

schedule = Biz::Schedule.new do |config|
  config.hours = {
    mon: {'07:00' => '18:00'},
    tue: {'07:00' => '18:00'},
    wed: {'07:00' => '18:00'},
    thu: {'07:00' => '18:00'},
    fri: {'07:00' => '18:00'}
  }
end

def days_after(schedule, number, start_time)
  if schedule.in_hours?(start_time)
    schedule.time(number, :days)
  else
    schedule.time(number + 1, :days)
  end.after(start_time)
end

friday = Time.utc(2016, 4, 1, 12)
sunday = Time.utc(2016, 4, 3, 12)

days_after(schedule, 1, sunday)
#=> 2016-04-05 12:00:00 UTC

days_after(schedule, 1, friday)
#=> 2016-04-04 12:00:00 UTC

Depending on how you're using biz, you'd probably be able to make this a bit nicer, but you get the idea.

Seem reasonable?

@mwean
Copy link
Author

mwean commented Apr 7, 2016

Yeah, that makes sense. I'm already wrapping it, so it's easy to handle, I just wanted to check that it was intentional behavior. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants