module ETL #:nodoc: module Builder #:nodoc: # A builder which will build a data structure which can be used to populate a date dimension using # commonly used date dimension columns. class DateDimensionBuilder # Specify the start date for the first record attr_accessor :start_date # Specify the end date for the last record attr_accessor :end_date # Define any holiday indicators attr_accessor :holiday_indicators # Add offset month for fiscal year attr_accessor :fiscal_year_offset_month # Define the weekday indicators. The default array begins on Sunday and goes to Saturday. cattr_accessor :weekday_indicators @@weekday_indicators = ['Weekend','Weekday','Weekday','Weekday','Weekday','Weekday','Weekend'] # Initialize the builder. # # * start_date: The start date. Defaults to 5 years ago from today. # * end_date: The end date. Defaults to now. def initialize(start_date=Time.now.years_ago(5), end_date=Time.now, fiscal_year_offset_month=10) @start_date = start_date.to_date @end_date = end_date.to_date @fiscal_year_offset_month = fiscal_year_offset_month.to_i @holiday_indicators = [] end # Returns an array of hashes representing records in the dimension. def build(options={}) (start_date..end_date).map { |date| record_from_date(date) } end private # Returns a hash representing a record in the dimension. The values for each record are # accessed by name. def record_from_date(date) time = date.to_time # need methods only available in Time record = {} record[:date] = time.strftime("%m/%d/%Y") record[:full_date_description] = time.strftime("%B %d,%Y") record[:day_of_week] = time.strftime("%A") record[:day_in_week] = record[:day_of_week] # alias #record[:day_number_in_epoch] = time.to_i / 24 #record[:week_number_in_epoch] = time.to_i / (24 * 7) #record[:month_number_in_epoch] = time.to_i / (24 * 7 * 30) record[:day_number_in_calendar_month] = time.day record[:day_number_in_calendar_year] = time.yday record[:day_number_in_fiscal_month] = time.day # should this be different from CY? record[:day_number_in_fiscal_year] = time.fiscal_year_yday(fiscal_year_offset_month) #record[:last_day_in_week_indicator] = #record[:last_day_in_month_indicator] = #record[:calendar_week_ending_date] = record[:calendar_week] = "Week #{time.week}" record[:calendar_week_number] = time.week record[:calendar_week_number_in_year] = time.week # DEPRECATED record[:calendar_month_name] = time.strftime("%B") record[:calendar_month_number_in_year] = time.month # DEPRECATED record[:calendar_month_number] = time.month record[:calendar_year_month] = time.strftime("%Y-%m") record[:calendar_quarter] = "Q#{time.quarter}" record[:calendar_quarter_number] = time.quarter record[:calendar_quarter_number_in_year] = time.quarter # DEPRECATED record[:calendar_year_quarter] = "#{time.strftime('%Y')}-#{record[:calendar_quarter]}" #record[:calendar_half_year] = record[:calendar_year] = "#{time.year}" record[:fiscal_week] = "FY Week #{time.fiscal_year_week(fiscal_year_offset_month)}" record[:fiscal_week_number_in_year] = time.fiscal_year_week(fiscal_year_offset_month) # DEPRECATED record[:fiscal_week_number] = time.fiscal_year_week(fiscal_year_offset_month) record[:fiscal_month] = time.fiscal_year_month(fiscal_year_offset_month) record[:fiscal_month_number] = time.fiscal_year_month(fiscal_year_offset_month) record[:fiscal_month_number_in_year] = time.fiscal_year_month(fiscal_year_offset_month) # DEPRECATED record[:fiscal_year_month] = "FY#{time.fiscal_year(fiscal_year_offset_month)}-" + time.fiscal_year_month(fiscal_year_offset_month).to_s.rjust(2, '0') record[:fiscal_quarter] = "FY Q#{time.fiscal_year_quarter(fiscal_year_offset_month)}" record[:fiscal_year_quarter] = "FY#{time.fiscal_year(fiscal_year_offset_month)}-Q#{time.fiscal_year_quarter(fiscal_year_offset_month)}" record[:fiscal_quarter_number] = time.fiscal_year_quarter(fiscal_year_offset_month) # DEPRECATED record[:fiscal_year_quarter_number] = time.fiscal_year_quarter(fiscal_year_offset_month) #record[:fiscal_half_year] = record[:fiscal_year] = "FY#{time.fiscal_year(fiscal_year_offset_month)}" record[:fiscal_year_number] = time.fiscal_year(fiscal_year_offset_month) record[:holiday_indicator] = holiday_indicators.include?(date) ? 'Holiday' : 'Nonholiday' record[:weekday_indicator] = weekday_indicators[time.wday] record[:selling_season] = 'None' record[:major_event] = 'None' record[:sql_date_stamp] = date record end end end end