Calculate next reporting date

It’s been a while since my last post. I’ve been hacking along though. Here’s an interesting puzzle I faced recently.

In the app, I have an model called Corporation. Each corporation has a reporting frequency, a start date and the timezone it’s in. The task is to calculate the next (and the last) reporting date for each corporation. It seems pretty straight forward, but the devil is in the details …

The trimmed down version of my implementation is below

class Corporation < ActiveRecord::Base

  REPORTING_FREQUENCY = %w(monthly bi-monthly quarterly half-yearly yearly)
  REPORTING_FREQUENCY_INCREMENTS = { 'monthly'     => 1.month,
                                     'bi-monthly'  => 2.months,
                                     'quarterly'   => 3.months,
                                     'half-yearly' => 6.months,
                                     'yearly'      => 12.months }

  def next_reporting_date
    now =

    return start_date if start_date > now

    reporting_date(now,, start_date)


  def reporting_date(now, original_start_day, start)
    if original_start_day > && >= original_start_day
      start = start + (original_start_day -

    return start if start >= now

    reporting_date(now, original_start_day, start + reporting_frequency_increment_value)

  def reporting_frequency_increment_value


The only tricky bit is the first if block inside the recursive reporting_date call. It makes sure we’re not losing days when we cycle through months that have less days than the value.

Hope I’m making sense here … and I’m sure there are existing algorithms out there doing what I want more elegantly.

Published: 2013-03-28
blog comments powered by Disqus