diff --git a/lib/date/format.rb b/lib/date/format.rb index 6894e94..268d945 100644 --- a/lib/date/format.rb +++ b/lib/date/format.rb @@ -108,28 +108,6 @@ class Date [MONTHS, DAYS, ABBR_MONTHS, ABBR_DAYS, ZONES].each do |x| x.freeze end - - class BagStruct < Struct # :nodoc: - - def to_hash - h = {} - members.each do |k| - unless /\A_/ =~ k.to_s || self[k].nil? - h[k] = self[k] - end - end - h - end - - end - - Bag = BagStruct.new(:year, :mon, :yday, :mday, :wday, - :cwyear, :cweek, :cwday, - :hour, :min, :sec, :sec_fraction, - :wnum0, :wnum1, :seconds, - :zone, :offset, :leftover, - :_cent, :_merid, :_comp) - end def emit(e, f) # :nodoc: @@ -398,20 +376,20 @@ class Date str.sub!(/\A(#{Format::ABBR_DAYS.keys.join('|')})/io, '') val = Format::DAYS[$1.downcase] || Format::ABBR_DAYS[$1.downcase] return unless val - e.wday = val + e[:wday] = val when 'B', 'b', 'h' return unless str.sub!(/\A(#{Format::MONTHS.keys.join('|')})/io, '') || str.sub!(/\A(#{Format::ABBR_MONTHS.keys.join('|')})/io, '') val = Format::MONTHS[$1.downcase] || Format::ABBR_MONTHS[$1.downcase] return unless val - e.mon = val + e[:mon] = val when 'C', 'EC' return unless str.sub!(if num_pattern?($') then /\A([-+]?\d{1,2})/ else /\A([-+]?\d{1,})/ end, '') val = $1.to_i - e._cent = val + e[:_][:cent] = val when 'c', 'Ec' return unless _strptime_i(str, '%a %b %e %H:%M:%S %Y', e) when 'D' @@ -420,7 +398,7 @@ class Date return unless str.sub!(/\A( \d|\d{1,2})/, '') val = $1.to_i return unless (1..31) === val - e.mday = val + e[:mday] = val when 'F' return unless _strptime_i(str, '%Y-%m-%d', e) when 'G' @@ -429,28 +407,28 @@ class Date else /\A([-+]?\d{1,})/ end, '') val = $1.to_i - e.cwyear = val + e[:cwyear] = val when 'g' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (0..99) === val - e.cwyear = val - e._cent ||= if val >= 69 then 19 else 20 end + e[:cwyear] = val + e[:_][:cent] ||= if val >= 69 then 19 else 20 end when 'H', 'k', 'OH' return unless str.sub!(/\A( \d|\d{1,2})/, '') val = $1.to_i return unless (0..24) === val - e.hour = val + e[:hour] = val when 'I', 'l', 'OI' return unless str.sub!(/\A( \d|\d{1,2})/, '') val = $1.to_i return unless (1..12) === val - e.hour = val + e[:hour] = val when 'j' return unless str.sub!(/\A(\d{1,3})/, '') val = $1.to_i return unless (1..366) === val - e.yday = val + e[:yday] = val when 'L' return unless str.sub!(if num_pattern?($') then /\A([-+]?\d{1,3})/ @@ -458,17 +436,17 @@ class Date end, '') # val = Rational($1.to_i, 10**3) val = Rational($1.to_i, 10**$1.size) - e.sec_fraction = val + e[:sec_fraction] = val when 'M', 'OM' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (0..59) === val - e.min = val + e[:min] = val when 'm', 'Om' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (1..12) === val - e.mon = val + e[:mon] = val when 'N' return unless str.sub!(if num_pattern?($') then /\A([-+]?\d{1,9})/ @@ -476,16 +454,16 @@ class Date end, '') # val = Rational($1.to_i, 10**9) val = Rational($1.to_i, 10**$1.size) - e.sec_fraction = val + e[:sec_fraction] = val when 'n', 't' return unless _strptime_i(str, "\s", e) when 'P', 'p' return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/i, '') - e._merid = if $1.downcase == 'a' then 0 else 12 end + e[:_][:merid] = if $1.downcase == 'a' then 0 else 12 end when 'Q' return unless str.sub!(/\A(-?\d{1,})/, '') val = Rational($1.to_i, 10**3) - e.seconds = val + e[:seconds] = val when 'R' return unless _strptime_i(str, '%H:%M', e) when 'r' @@ -494,35 +472,35 @@ class Date return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (0..60) === val - e.sec = val + e[:sec] = val when 's' return unless str.sub!(/\A(-?\d{1,})/, '') val = $1.to_i - e.seconds = val + e[:seconds] = val when 'T' return unless _strptime_i(str, '%H:%M:%S', e) when 'U', 'W', 'OU', 'OW' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (0..53) === val - e.__send__(if s[-1,1] == 'U' then :wnum0= else :wnum1= end, val) + e[s[-1,1] == 'U' ? :wnum0 : :wnum1] = val when 'u', 'Ou' return unless str.sub!(/\A(\d{1})/, '') val = $1.to_i return unless (1..7) === val - e.cwday = val + e[:cwday] = val when 'V', 'OV' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (1..53) === val - e.cweek = val + e[:cweek] = val when 'v' return unless _strptime_i(str, '%e-%b-%Y', e) when 'w' return unless str.sub!(/\A(\d{1})/, '') val = $1.to_i return unless (0..6) === val - e.wday = val + e[:wday] = val when 'X', 'EX' return unless _strptime_i(str, '%H:%M:%S', e) when 'x', 'Ex' @@ -533,22 +511,22 @@ class Date else /\A([-+]?\d{1,})/ end, '') val = $1.to_i - e.year = val + e[:year] = val when 'y', 'Ey', 'Oy' return unless str.sub!(/\A(\d{1,2})/, '') val = $1.to_i return unless (0..99) === val - e.year = val - e._cent ||= if val >= 69 then 19 else 20 end + e[:year] = val + e[:_][:cent] ||= if val >= 69 then 19 else 20 end when 'Z', /\A:{0,3}z/ return unless str.sub!(/\A((?:gmt|utc?)?[-+]\d+(?:[,.:]\d+(?::\d+)?)? |[[:alpha:].\s]+(?:standard|daylight)\s+time\b |[[:alpha:]]+(?:\s+dst)?\b )/ix, '') val = $1 - e.zone = val + e[:zone] = val offset = zone_to_diff(val) - e.offset = offset + e[:offset] = offset when '%' return unless str.sub!(/\A%/, '') when '+' @@ -571,30 +549,31 @@ class Date def self._strptime(str, fmt='%F') str = str.dup - e = Format::Bag.new + e = {:_ => {}} return unless _strptime_i(str, fmt, e) - if e._cent - if e.cwyear - e.cwyear += e._cent * 100 + if e[:_][:cent] + if e[:cwyear] + e[:cwyear] += e[:_][:cent] * 100 end - if e.year - e. year += e._cent * 100 + if e[:year] + e[:year] += e[:_][:cent] * 100 end end - if e._merid - if e.hour - e.hour %= 12 - e.hour += e._merid + if e[:_][:merid] + if e[:hour] + e[:hour] %= 12 + e[:hour] += e[:_][:merid] end end unless str.empty? - e.leftover = str + e[:leftover] = str end - e.to_hash + e.delete(:_) + e end def self.s3e(e, y, m, d, bc=false) @@ -645,21 +624,21 @@ class Date if bc iy = -iy + 1 end - e.year = iy + e[:year] = iy end if m m =~ /\d+/ - e.mon = $&.to_i + e[:mon] = $&.to_i end if d d =~ /\d+/ - e.mday = $&.to_i + e[:mday] = $&.to_i end if c != nil - e._comp = c + e[:_][:comp] = c end end @@ -668,11 +647,11 @@ class Date def self._parse_day(str, e) # :nodoc: if str.sub!(/\b(#{Format::ABBR_DAYS.keys.join('|')})[^-\d\s]*/io, ' ') - e.wday = Format::ABBR_DAYS[$1.downcase] + e[:wday] = Format::ABBR_DAYS[$1.downcase] true =begin elsif str.sub!(/\b(?!\dth)(su|mo|tu|we|th|fr|sa)\b/i, ' ') - e.wday = %w(su mo tu we th fr sa).index($1.downcase) + e[:wday] = %w(su mo tu we th fr sa).index($1.downcase) true =end end @@ -710,7 +689,7 @@ class Date ' ') t = $1 - e.zone = $2 if $2 + e[:zone] = $2 if $2 t =~ /\A(\d+)h? (?:\s*:?\s*(\d+)m? @@ -720,15 +699,15 @@ class Date )? (?:\s*([ap])(?:m\b|\.m\.))?/ix - e.hour = $1.to_i - e.min = $2.to_i if $2 - e.sec = $3.to_i if $3 - e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4 + e[:hour] = $1.to_i + e[:min] = $2.to_i if $2 + e[:sec] = $3.to_i if $3 + e[:sec_fraction] = Rational($4.to_i, 10**$4.size) if $4 if $5 - e.hour %= 12 + e[:hour] %= 12 if $5.downcase == 'p' - e.hour += 12 + e[:hour] += 12 end end true @@ -742,11 +721,11 @@ class Date beat += Rational($2.to_i, 10**$2.size) if $2 secs = Rational(beat, 1000) h, min, s, fr = self.day_fraction_to_time(secs) - e.hour = h - e.min = min - e.sec = s - e.sec_fraction = fr * 86400 - e.zone = '+01:00' + e[:hour] = h + e[:min] = min + e[:sec] = s + e[:sec_fraction] = fr * 86400 + e[:zone] = '+01:00' true end end @@ -799,29 +778,29 @@ class Date def self._parse_iso2(str, e) # :nodoc: if str.sub!(/\b(\d{2}|\d{4})?-?w(\d{2})(?:-?(\d))?\b/i, ' ') - e.cwyear = $1.to_i if $1 - e.cweek = $2.to_i - e.cwday = $3.to_i if $3 + e[:cwyear] = $1.to_i if $1 + e[:cweek] = $2.to_i + e[:cwday] = $3.to_i if $3 true elsif str.sub!(/-w-(\d)\b/i, ' ') - e.cwday = $1.to_i + e[:cwday] = $1.to_i true elsif str.sub!(/--(\d{2})?-(\d{2})\b/, ' ') - e.mon = $1.to_i if $1 - e.mday = $2.to_i + e[:mon] = $1.to_i if $1 + e[:mday] = $2.to_i true elsif str.sub!(/--(\d{2})(\d{2})?\b/, ' ') - e.mon = $1.to_i - e.mday = $2.to_i if $2 + e[:mon] = $1.to_i + e[:mday] = $2.to_i if $2 true elsif /[,.](\d{2}|\d{4})-\d{3}\b/ !~ str && str.sub!(/\b(\d{2}|\d{4})-(\d{3})\b/, ' ') - e.year = $1.to_i - e.yday = $2.to_i + e[:year] = $1.to_i + e[:yday] = $2.to_i true elsif /\d-\d{3}\b/ !~ str && str.sub!(/\b-(\d{3})\b/, ' ') - e.yday = $1.to_i + e[:yday] = $1.to_i true end end @@ -833,9 +812,9 @@ class Date 's'=>1925, 'h'=>1988 }[$1.downcase] - e.year = $2.to_i + era - e.mon = $3.to_i - e.mday = $4.to_i + e[:year] = $2.to_i + era + e[:mon] = $3.to_i + e[:mday] = $4.to_i true end end @@ -868,21 +847,21 @@ class Date def self._parse_year(str, e) # :nodoc: if str.sub!(/'(\d+)\b/, ' ') - e.year = $1.to_i + e[:year] = $1.to_i true end end def self._parse_mon(str, e) # :nodoc: if str.sub!(/\b(#{Format::ABBR_MONTHS.keys.join('|')})\S*/io, ' ') - e.mon = Format::ABBR_MONTHS[$1.downcase] + e[:mon] = Format::ABBR_MONTHS[$1.downcase] true end end def self._parse_mday(str, e) # :nodoc: if str.sub!(/(\d+)(st|nd|rd|th)\b/i, ' ') - e.mday = $1.to_i + e[:mday] = $1.to_i true end end @@ -911,109 +890,109 @@ class Date case $2.size when 2 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i + e[:sec] = $2[-2, 2].to_i else - e.mday = $2[ 0, 2].to_i + e[:mday] = $2[ 0, 2].to_i end when 4 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-4, 2].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-4, 2].to_i else - e.mon = $2[ 0, 2].to_i - e.mday = $2[ 2, 2].to_i + e[:mon] = $2[ 0, 2].to_i + e[:mday] = $2[ 2, 2].to_i end when 6 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-4, 2].to_i - e.hour = $2[-6, 2].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-4, 2].to_i + e[:hour] = $2[-6, 2].to_i else - e.year = ($1 + $2[ 0, 2]).to_i - e.mon = $2[ 2, 2].to_i - e.mday = $2[ 4, 2].to_i + e[:year] = ($1 + $2[ 0, 2]).to_i + e[:mon] = $2[ 2, 2].to_i + e[:mday] = $2[ 4, 2].to_i end when 8, 10, 12, 14 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-4, 2].to_i - e.hour = $2[-6, 2].to_i - e.mday = $2[-8, 2].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-4, 2].to_i + e[:hour] = $2[-6, 2].to_i + e[:mday] = $2[-8, 2].to_i if $2.size >= 10 - e.mon = $2[-10, 2].to_i + e[:mon] = $2[-10, 2].to_i end if $2.size == 12 - e.year = ($1 + $2[-12, 2]).to_i + e[:year] = ($1 + $2[-12, 2]).to_i end if $2.size == 14 - e.year = ($1 + $2[-14, 4]).to_i - e._comp = false + e[:year] = ($1 + $2[-14, 4]).to_i + e[:_][:comp] = false end else - e.year = ($1 + $2[ 0, 4]).to_i - e.mon = $2[ 4, 2].to_i - e.mday = $2[ 6, 2].to_i - e.hour = $2[ 8, 2].to_i if $2.size >= 10 - e.min = $2[10, 2].to_i if $2.size >= 12 - e.sec = $2[12, 2].to_i if $2.size >= 14 - e._comp = false + e[:year] = ($1 + $2[ 0, 4]).to_i + e[:mon] = $2[ 4, 2].to_i + e[:mday] = $2[ 6, 2].to_i + e[:hour] = $2[ 8, 2].to_i if $2.size >= 10 + e[:min] = $2[10, 2].to_i if $2.size >= 12 + e[:sec] = $2[12, 2].to_i if $2.size >= 14 + e[:_][:comp] = false end when 3 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-3, 1].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-3, 1].to_i else - e.yday = $2[ 0, 3].to_i + e[:yday] = $2[ 0, 3].to_i end when 5 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-4, 2].to_i - e.hour = $2[-5, 1].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-4, 2].to_i + e[:hour] = $2[-5, 1].to_i else - e.year = ($1 + $2[ 0, 2]).to_i - e.yday = $2[ 2, 3].to_i + e[:year] = ($1 + $2[ 0, 2]).to_i + e[:yday] = $2[ 2, 3].to_i end when 7 if $3.nil? && $4 - e.sec = $2[-2, 2].to_i - e.min = $2[-4, 2].to_i - e.hour = $2[-6, 2].to_i - e.mday = $2[-7, 1].to_i + e[:sec] = $2[-2, 2].to_i + e[:min] = $2[-4, 2].to_i + e[:hour] = $2[-6, 2].to_i + e[:mday] = $2[-7, 1].to_i else - e.year = ($1 + $2[ 0, 4]).to_i - e.yday = $2[ 4, 3].to_i + e[:year] = ($1 + $2[ 0, 4]).to_i + e[:yday] = $2[ 4, 3].to_i end end if $3 if $4 case $3.size when 2, 4, 6 - e.sec = $3[-2, 2].to_i - e.min = $3[-4, 2].to_i if $3.size >= 4 - e.hour = $3[-6, 2].to_i if $3.size >= 6 + e[:sec] = $3[-2, 2].to_i + e[:min] = $3[-4, 2].to_i if $3.size >= 4 + e[:hour] = $3[-6, 2].to_i if $3.size >= 6 end else case $3.size when 2, 4, 6 - e.hour = $3[ 0, 2].to_i - e.min = $3[ 2, 2].to_i if $3.size >= 4 - e.sec = $3[ 4, 2].to_i if $3.size >= 6 + e[:hour] = $3[ 0, 2].to_i + e[:min] = $3[ 2, 2].to_i if $3.size >= 4 + e[:sec] = $3[ 4, 2].to_i if $3.size >= 6 end end end if $4 - e.sec_fraction = Rational($4.to_i, 10**$4.size) + e[:sec_fraction] = Rational($4.to_i, 10**$4.size) end if $5 - e.zone = $5 - if e.zone[0,1] == '[' - o, n, = e.zone[1..-2].split(':') - e.zone = n || o + e[:zone] = $5 + if e[:zone][0,1] == '[' + o, n, = e[:zone][1..-2].split(':') + e[:zone] = n || o if /\A\d/ =~ o o = format('+%s', o) end - e.offset = zone_to_diff(o) + e[:offset] = zone_to_diff(o) end end true @@ -1028,10 +1007,7 @@ class Date def self._parse(str, comp=true) str = str.dup - e = Format::Bag.new - - e._comp = comp - + e = {:_ => {:comp => comp}} str.gsub!(/[^-+',.\/:@[:alnum:]\[\]]+/, ' ') _parse_time(str, e) # || _parse_beat(str, e) @@ -1051,44 +1027,45 @@ class Date _parse_ddd(str, e) if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/i, ' ') - if e.year - e.year = -e.year + 1 + if e[:year] + e[:year] = -e[:year] + 1 end end if str.sub!(/\A\s*(\d{1,2})\s*\z/, ' ') - if e.hour && !e.mday + if e[:hour] && !e[:mday] v = $1.to_i if (1..31) === v - e.mday = v + e[:mday] = v end end - if e.mday && !e.hour + if e[:mday] && !e[:hour] v = $1.to_i if (0..24) === v - e.hour = v + e[:hour] = v end end end - if e._comp - if e.cwyear - if e.cwyear >= 0 && e.cwyear <= 99 - e.cwyear += if e.cwyear >= 69 + if e[:_][:comp] + if e[:cwyear] + if e[:cwyear] >= 0 && e[:cwyear] <= 99 + e[:cwyear] += if e[:cwyear] >= 69 then 1900 else 2000 end end end - if e.year - if e.year >= 0 && e.year <= 99 - e.year += if e.year >= 69 + if e[:year] + if e[:year] >= 0 && e[:year] <= 99 + e[:year] += if e[:year] >= 69 then 1900 else 2000 end end end end - e.offset ||= zone_to_diff(e.zone) if e.zone + e[:offset] ||= zone_to_diff(e[:zone]) if e[:zone] - e.to_hash + e.delete(:_) + e end def self._iso8601(str) # :nodoc: @@ -1130,42 +1107,42 @@ class Date (?:t (\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?)? (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str - e = Format::Bag.new - e.year = $1.to_i - e.mon = $2.to_i if $2 - e.mday = $3.to_i if $3 - e.hour = $4.to_i if $4 - e.min = $5.to_i if $5 - e.sec = $6.to_i if $6 - e.sec_fraction = Rational($7.to_i, 10**$7.size) if $7 + e = {} + e[:year] = $1.to_i + e[:mon] = $2.to_i if $2 + e[:mday] = $3.to_i if $3 + e[:hour] = $4.to_i if $4 + e[:min] = $5.to_i if $5 + e[:sec] = $6.to_i if $6 + e[:sec_fraction] = Rational($7.to_i, 10**$7.size) if $7 if $8 - e.zone = $8 - e.offset = zone_to_diff($8) + e[:zone] = $8 + e[:offset] = zone_to_diff($8) end - e.to_hash + e elsif /\A\s*(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))? (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str - e = Format::Bag.new - e.hour = $1.to_i if $1 - e.min = $2.to_i if $2 - e.sec = $3.to_i if $3 - e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4 + e = {} + e[:hour] = $1.to_i if $1 + e[:min] = $2.to_i if $2 + e[:sec] = $3.to_i if $3 + e[:sec_fraction] = Rational($4.to_i, 10**$4.size) if $4 if $5 - e.zone = $5 - e.offset = zone_to_diff($5) + e[:zone] = $5 + e[:offset] = zone_to_diff($5) end - e.to_hash + e elsif /\A\s*(?:--(\d{2})(?:-(\d{2}))?|---(\d{2})) (z|[-+]\d{2}:\d{2})?\s*\z/ix =~ str - e = Format::Bag.new - e.mon = $1.to_i if $1 - e.mday = $2.to_i if $2 - e.mday = $3.to_i if $3 + e = {} + e[:mon] = $1.to_i if $1 + e[:mday] = $2.to_i if $2 + e[:mday] = $3.to_i if $3 if $4 - e.zone = $4 - e.offset = zone_to_diff($4) + e[:zone] = $4 + e[:offset] = zone_to_diff($4) end - e.to_hash + e end end