Feature #4452 ยป date_format.patch
| lib/date/format.rb | ||
|---|---|---|
|     [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: | ||
| ... | ... | |
| 			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' | ||
| ... | ... | |
| 	  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' | ||
| ... | ... | |
| 				 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})/ | ||
| ... | ... | |
| 				 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})/ | ||
| ... | ... | |
| 				 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' | ||
| ... | ... | |
| 	  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' | ||
| ... | ... | |
| 				 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 '+' | ||
| ... | ... | |
|   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) | ||
| ... | ... | |
|       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 | ||
| ... | ... | |
|   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 | ||
| ... | ... | |
| 		' ') | ||
|       t = $1 | ||
|       e.zone = $2 if $2 | ||
|       e[:zone] = $2 if $2 | ||
|       t =~ /\A(\d+)h? | ||
| 	      (?:\s*:?\s*(\d+)m? | ||
| ... | ... | |
| 	      )? | ||
| 	    (?:\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 | ||
| ... | ... | |
|       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 | ||
| ... | ... | |
|   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 | ||
| ... | ... | |
| 	      '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 | ||
| ... | ... | |
|   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 | ||
| ... | ... | |
|       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 | ||
| ... | ... | |
|   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) | ||
| ... | ... | |
|     _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: | ||
| ... | ... | |
| 	(?: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 | ||