Method: Date.parse_spec
- Defined in:
- lib/fat_core/date.rb
.parse_spec(spec, spec_type = :from) ⇒ Object
Convert a ‘date spec’ to a Date. A date spec is a short-hand way of
a date, relative to the computer clock. A date spec can
interpreted as either a 'from spec' or a 'to spec'.
@example
Assuming that Date.current at the time of execution is 2014-07-26 and
using the default spec_type of :from. The return values are actually Date
objects, but are shown below as textual dates.
A fully specified date returns that date:
Date.parse_spec('2001-09-11') # =>
Commercial weeks can be specified using, for example W32 or 32W, with the
week beginning on Monday, ending on Sunday.
Date.parse_spec('2012-W32') # =>
Date.parse_spec('2012-W32', :to) # =>
Date.parse_spec('W32') # =>
A spec of the form Q3 or 3Q returns the beginning or end of calendar
quarters.
Date.parse_spec('Q3') # =>
@param spec [#to_s] a stringling containing the spec to be interpreted
@param spec_type [:from, :to] interpret the spec as a from- or to-spec
respectively, defaulting to interpretation as a to-spec.
@return [Date] a date object equivalent to the date spec
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/fat_core/date.rb', line 66 def self.parse_spec(spec, spec_type = :from) spec = spec.to_s.strip unless [:from, :to].include?(spec_type) raise ArgumentError "invalid date spec type: '#{spec_type}'" end today = Date.current case spec when /^(\d\d\d\d)-(\d\d?)-(\d\d?)*$/ # A specified date Date.new($1.to_i, $2.to_i, $3.to_i) when /\AW(\d\d?)\z/, /\A(\d\d?)W\z/ week_num = $1.to_i if week_num < 1 || week_num > 53 raise ArgumentError, "invalid week number (1-53): 'W#{week_num}'" end spec_type == :from ? Date.commercial(today.year, week_num).beginning_of_week : Date.commercial(today.year, week_num).end_of_week when /\A(\d\d\d\d)-W(\d\d?)\z/, /\A(\d\d\d\d)-(\d\d?)W\z/ year = $1.to_i week_num = $2.to_i if week_num < 1 || week_num > 53 raise ArgumentError, "invalid week number (1-53): 'W#{week_num}'" end spec_type == :from ? Date.commercial(year, week_num).beginning_of_week : Date.commercial(year, week_num).end_of_week when /^(\d\d\d\d)-(\d)[Qq]$/, /^(\d\d\d\d)-[Qq](\d)$/ # Year-Quarter year = $1.to_i quarter = $2.to_i unless [1, 2, 3, 4].include?(quarter) raise ArgumentError, "bad date format: #{spec}" end month = quarter * 3 spec_type == :from ? Date.new(year, month, 1).beginning_of_quarter : Date.new(year, month, 1).end_of_quarter when /^([1234])[qQ]$/, /^[qQ]([1234])$/ # Quarter only this_year = today.year quarter = $1.to_i date = Date.new(this_year, quarter * 3, 15) spec_type == :from ? date.beginning_of_quarter : date.end_of_quarter when /^(\d\d\d\d)-(\d\d?)*$/ # Year-Month only spec_type == :from ? Date.new($1.to_i, $2.to_i, 1) : Date.new($1.to_i, $2.to_i, 1).end_of_month when /\A(\d\d?)\z/ # Month only spec_type == :from ? Date.new(today.year, $1.to_i, 1) : Date.new(today.year, $1.to_i, 1).end_of_month when /^(\d\d\d\d)$/ # Year only spec_type == :from ? Date.new($1.to_i, 1, 1) : Date.new($1.to_i, 12, 31) when /^(to|this_?)?day/ today when /^(yester|last_?)?day/ today - 1.day when /^(this_?)?week/ spec_type == :from ? today.beginning_of_week : today.end_of_week when /last_?week/ spec_type == :from ? (today - 1.week).beginning_of_week : (today - 1.week).end_of_week when /^(this_?)?biweek/ spec_type == :from ? today.beginning_of_biweek : today.end_of_biweek when /last_?biweek/ spec_type == :from ? (today - 2.week).beginning_of_biweek : (today - 2.week).end_of_biweek when /^(this_?)?semimonth/ spec_type == :from ? today.beginning_of_semimonth : today.end_of_semimonth when /^last_?semimonth/ spec_type == :from ? (today - 15.days).beginning_of_semimonth : (today - 15.days).end_of_semimonth when /^(this_?)?month/ spec_type == :from ? today.beginning_of_month : today.end_of_month when /^last_?month/ spec_type == :from ? (today - 1.month).beginning_of_month : (today - 1.month).end_of_month when /^(this_?)?bimonth/ spec_type == :from ? today.beginning_of_bimonth : today.end_of_bimonth when /^last_?bimonth/ spec_type == :from ? (today - 2.month).beginning_of_bimonth : (today - 2.month).end_of_bimonth when /^(this_?)?quarter/ spec_type == :from ? today.beginning_of_quarter : today.end_of_quarter when /^last_?quarter/ spec_type == :from ? (today - 3.months).beginning_of_quarter : (today - 3.months).end_of_quarter when /^(this_?)?year/ spec_type == :from ? today.beginning_of_year : today.end_of_year when /^last_?year/ spec_type == :from ? (today - 1.year).beginning_of_year : (today - 1.year).end_of_year when /^forever/ spec_type == :from ? Date::BOT : Date::EOT when /^never/ nil else raise ArgumentError, "bad date spec: '#{spec}''" end # !> previous definition of length was here end |