Hatena::Grouprubyist

entottoの日記

2009-02-06jparsedate

オブジェクト指向でやってみた 15:03

元ねた: g:rubyist:id:priny:20090202

オーバースペック気味だけど、オブジェクト指向で

$KCODE = "u"
class ResettableValue
  attr_accessor :dependents, :value, :reset_value
  def initialize(value, reset_value)
    self.value = value
    self.reset_value = reset_value
  end

  def reset
    self.value = self.reset_value
  end

  def update(value)
    self.value = value
    self.dependents.each do |each|
      each.reset
    end if self.dependents
  end
end

def jparsedate(str)
  now = Time.now
  year = ResettableValue.new(now.year, 1)
  month = ResettableValue.new(now.month, 1)
  day = ResettableValue.new(now.day, 1)
  hour = ResettableValue.new(now.hour, 0)
  min = ResettableValue.new(now.min, 0)
  sec = ResettableValue.new(0, 0)

  year.dependents = [month, day, hour, min]
  month.dependents = [day, hour, min]
  day.dependents = [hour, min]
  hour.dependents = [min]

  elements = {
    "" => year,
    "" => month,
    "" => day,
    "" => hour,
    "" => min,
    "" => sec
  }

  str.scan(/([午前|午後]*)?(\d*)([年|月|日|時|分|秒])/){
    val = elements[$3]
    newval = $2
    if "" == $3 and "午後" == $1
      newval = $2.to_i + 12
    end
    if val
      val.update newval
    end
  }
  values = [year, month, day, hour, min, sec].collect do |each| each.value end
  Time.mktime(*values)
end

p jparsedate("2001年12月23日午後8時17分50秒")
p jparsedate("01年12月23日午前8時50秒")
p jparsedate("12月23日午後10時")
p jparsedate("2001年12月")
p jparsedate("8時17分50秒")
p jparsedate("50秒")

実行結果

$ ruby jparsedate_oo.rb 
Sun Dec 23 20:17:50 +0900 2001
Sun Dec 23 08:00:50 +0900 2001
Wed Dec 23 22:00:00 +0900 2009
Sat Dec 01 00:00:00 +0900 2001
Fri Feb 06 08:17:50 +0900 2009
Fri Feb 06 14:36:50 +0900 2009

制約に頼ってみた 15:03

g:rubyist:id:entotto:20090206 続き

ここでの制約は、「一時データが"秒","分","時","日","月","年"の順に並んでいること」

$KCODE = "u"
def jparsedate(str)
  now = Time.now
  units = ["","","","","",""]
  values = now.to_a[0..units.length-1]
  defaults = [0, 0, 0, 1, 1, 1]

  str.scan(/([午前|午後]*)?(\d*)([年|月|日|時|分|秒])/){
    unit = units.index($3)
    newval = ("" == $3 and "午後" == $1) ? $2.to_i+12 : $2
    if unit
      values[unit] = newval
      values[0..unit-1] = defaults[0..unit-1] if unit > 0
    else
      p unit, $3, units
    end
  }
  Time.mktime(*values.reverse)
end

p jparsedate("2001年12月23日午後8時17分50秒")
p jparsedate("01年12月23日午前8時50秒")
p jparsedate("12月23日午後10時")
p jparsedate("2001年12月")
p jparsedate("8時17分50秒")
p jparsedate("50秒")

実行結果

$ ruby jparsedate.rb 
Sun Dec 23 20:17:50 +0900 2001
Sun Dec 23 08:00:50 +0900 2001
Wed Dec 23 22:00:00 +0900 2009
Sat Dec 01 00:00:00 +0900 2001
Fri Feb 06 08:17:50 +0900 2009
Fri Feb 06 14:34:50 +0900 2009
トラックバック - http://rubyist.g.hatena.ne.jp/entotto/20090206