Skip to content

olleolleolle/business

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Business

Gem version Build status

Date calculations based on business calendars.

Documentation

Getting started

Get stareted with business by creating an instance of the calendar class, passing in a hash that specifies with days of the week are considered working days, and which days are holidays.

calendar = Business::Calendar.new(
  working_days: %w( mon tue wed thu fri ),
  holidays: ["01/01/2014", "03/01/2014"]
)

A few calendar configs are bundled with the gem (see lib/business/data for details). Load them by calling the load class method on Calendar. The load_cached variant of this method caches the calendars by name after loading them, to avoid reading and parsing the config file multiple times.

calendar = Business::Calendar.load("weekdays")
calendar = Business::Calendar.load_cached("weekdays")

Checking for business days

To check whether a given date is a business day (falls on one of the specified working days, and is not a holiday), use the business_day? method on Calendar.

calendar.business_day?(Date.parse("Monday, 9 June 2014"))
# => true
calendar.business_day?(Date.parse("Sunday, 8 June 2014"))
# => false

Business day arithmetic

The add_business_days and subtract_business_days are used to perform business day arithemtic on dates.

date = Date.parse("Thursday, 12 June 2014")
calendar.add_business_days(date, 4).strftime("%A, %d %B %Y")
# => "Wednesday, 18 June 2014"
calendar.subtract_business_days(date, 4).strftime("%A, %d %B %Y")
# => "Friday, 06 June 2014"

The roll_forward and roll_backward methods snap a date to a nearby business day. If provided with a business day, they will return that date. Otherwise, they will advance (forward for roll_forward and backward for roll_backward) until a business day is found.

date = Date.parse("Saturday, 14 June 2014")
calendar.roll_forward(date).strftime("%A, %d %B %Y")
# => "Monday, 16 June 2014"
calendar.roll_backward(date).strftime("%A, %d %B %Y")
# => "Friday, 13 June 2014"

To count the number of business days between two dates, pass the dates to business_days_between. This method counts from start of the first date to start of the second date. So, assuming no holidays, there would be two business days between a Monday and a Wednesday.

date = Date.parse("Saturday, 14 June 2014")
calendar.business_days_between(date, date + 7)
# => 5

But other libraries already do this

Another gem, business_time, also exists for this purpose. We previously used business_time, but encountered several issues that prompted us to start business.

Firstly, business_time works by monkey-patching Date, Time, and FixNum. While this enables syntax like Time.now + 1.business_day, it means that all configuration has to be global. GoCardless handles payments across several geographies, so being able to work with multiple working-day calendars is essential for us. Business provides a simple Calendar class, that is initialized with a configuration that specifies which days of the week are considered to be working days, and which dates are holidays.

Secondly, business_time supports calculations on times as well as dates. For our purposes, date-based calculations are sufficient. Supporting time-based calculations as well makes the code significantly more complex. We chose to avoid this extra complexity by sticking solely to date-based mathematics.

I'm late for business

About

Ruby business day calculations

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 100.0%