lib/fat_period/period.rb in fat_period-1.4.0 vs lib/fat_period/period.rb in fat_period-1.5.0

- old
+ new

@@ -25,12 +25,12 @@ # @param last [Date, String] last date of Period # @raise [ArgumentError] if string is not parseable as a Date or # @raise [ArgumentError] if first date is later than last date # @return [Period] def initialize(first, last) - @first = Date.ensure_date(first).freeze - @last = Date.ensure_date(last).freeze + @first = Date.ensure(first).freeze + @last = Date.ensure(last).freeze freeze raise ArgumentError, "Period's first date is later than its last date" if @first > @last end @@ -68,11 +68,11 @@ Period.new(first, second) if first && second end PHRASE_RE = %r{\A # One or both of from and to parts - (((from)?\s+(?<from_part>[-_a-z0-9]+)\s*)? + (((from)?\s*(?<from_part>[-_a-z0-9]+)\s*)? (to\s+(?<to_part>[-_a-z0-9]+))?) # Wholly optional chunk part (\s+per\s+(?<chunk_part>\w+))?\z}xi private_constant :PHRASE_RE @@ -164,10 +164,35 @@ else "#{first.iso} to #{last.iso}" end end + # Convert a string or Period into a Period object, if the string is parsable + # as a period. + # + # @example + # Period.ensure('2023-1q') #=> Period 2023-01-01..2023-03-31 + # pd = Period.new('2016-01-01', '2016-12-31') + # Period.ensure(pd) #=> pd # No effect + # + # @return [Period] either parsed String or same Period + def self.ensure(pd) + case pd + when Period + pd + when String + if pd.match?(/\s*from/i) + # Ignore any chunk modifier, 'per' + Period.parse_phrase(pd).first + else + Period.parse(pd) + end + else + raise UserError, "can't ensure `#{pd}` of #{pd.class} is a Period" + end + end + # A concise way to print out Periods for inspection as # 'Period(YYYY-MM-DD..YYYY-MM-DD)'. # # @return [String] def inspect @@ -369,10 +394,10 @@ raise ArgumentError, 'chunk is nil' unless chunk chunk = chunk.to_sym raise ArgumentError, "unknown chunk name: #{chunk}" unless CHUNKS.include?(chunk) - date = Date.ensure_date(date) + date = Date.ensure(date) method = "#{chunk}_containing".to_sym send(method, date) end # Return a Period representing a chunk containing today.