Friday, 21 September 2007

quarter-master

Continuing my series of "why isn't this in ruby already?", we have some date functions that allow us to add and display the current financial quarter. I have even overridden "strftime" to accept the symbol '%Q' to display the quarter.

class Time
  # save the original strftime so we can call it later
  alias original_strftime :strftime
  # overload strftime to accept '%Q' to display the quarter
  def strftime(format)
    format = format.gsub('%Q', "Q#{self.quarter.to_s}") if format
    self.original_strftime format
  end

  # create a utc time using the year and financial quarter
  def self.utc_fq(year, fq = 1)
    self.utc(year, self.quarter_to_month(fq))
  end
  # create a local time using the year and financial quarter
  def self.local_fq(year, fq = 1)
    self.local(year, self.quarter_to_month(fq))
  end

  # turns a financial quarter (1-4) into the first month of that quarter
  def self.quarter_to_month(fq)
    ((fq-1)  * 3) + 1
  end
  # turns a given month (1-12) into the financial quarter
  # (1=jan-mar, 2=apr-jun, 3=jul-sep, 4=oct-dec)
  def self.month_to_quarter(month)
    ((month - 1) / 3) + 1
  end

  # returns the financial quarter of this date
  # (1=jan-mar, 2=apr-jun, 3=jul-sep, 4=oct-dec)
  def quarter
    self.class.month_to_quarter(self.month)
  end
end

Example of use:

>> order_fq = Time.utc_fq(order.created_at.year, order.created_at.quarter)
=> Sun Jul 01 00:00:00 UTC 2007
>> p "Order's financial quarter: #{order_fq.strftime("%Y-%Q")}"
"Order's financial quarter: 2007-Q3"
=> nil

No comments: