We just open-sourced business, a simple library for doing business date calculations.

Usage

calendar = Business : : Calendar . new ( working_days : %w( mon tue wed thu fri ) , holidays : [ "01/01/2014" , "03/01/2014" ] ) calendar . business_day ? ( Date . parse ( "Monday, 9 June 2014" ) ) calendar . business_day ? ( Date . parse ( "Sunday, 8 June 2014" ) ) date = Date . parse ( "Thursday, 12 June 2014" ) calendar . add_business_days ( date , 4 ) . strftime ( "%A, %d %B %Y" ) calendar . subtract_business_days ( date , 4 ) . strftime ( "%A, %d %B %Y" ) date = Date . parse ( "Saturday, 14 June 2014" ) calendar . business_days_between ( date , date + 7 )

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, businesstime works by monkey-patching Date , Time , and FixNum . While this enables syntax like `Time.now + 1.businessday , 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.