summaryrefslogtreecommitdiff
path: root/lib/parsedate.rb
blob: 68550c65056769782d1c556093a58ed8fb90e7a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
module ParseDate
  MONTHS = {
    'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4,
    'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
    'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 }
  MONTHPAT = MONTHS.keys.join('|')
  DAYS = {
    'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
    'thu' => 4, 'fri' => 5, 'sat' => 6 }
  DAYPAT = DAYS.keys.join('|')
  
  def parsedate(date) 
    # part of ISO 8601
    # yyyy-mm-dd | yyyy-mm | yyyy
    # date hh:mm:ss | date Thh:mm:ss
    if date =~ /^(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)? *T?(?:(\d\d):?(\d\d):?(\d\d)?)?$/
      return $1.to_i,
	if $2 then $2.to_i else 1 end,
	if $3 then $3.to_i else 1 end,
	if $4 then $4.to_i end,
	if $5 then $5.to_i end,
	if $6 then $6.to_i end,
	nil,
	nil
    end
    date = date.dup
    if date.sub!(/(#{DAYPAT})[a-z]*,?/i, ' ')
      wday = DAYS[$1.downcase]
    end
    if date.sub!(/(\d+):(\d+)(?::(\d+))?\s*(am|pm)?\s*(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4})?|[-+]\d{4}))?/i, ' ')
      hour = $1.to_i
      min = $2.to_i
      if $3
	sec = $3.to_i
      end
      if $4 == 'pm'
	hour += 12
      end
      if $5
	zone = $5
      end
    end
    if date.sub!(/(\d+)\S*\s+(#{MONTHPAT})\S*(?:\s+(\d+))?/i, ' ')
      mday = $1.to_i
      mon = MONTHS[$2.downcase]
      if $3
	year = $3.to_i
      end
    elsif date.sub!(/(#{MONTHPAT})\S*\s+(\d+)\S*\s*,?(?:\s+(\d+))?/i, ' ')
      mon = MONTHS[$1.downcase]
      mday = $2.to_i
      if $3
	year = $3.to_i
      end
    elsif date.sub!(/(\d+)\/(\d+)(?:\/(\d+))/, ' ')
      mon = $1.to_i
      mday = $2.to_i
      if $3
	year = $3.to_i
      end
    end
    return year, mon, mday, hour, min, sec, zone, wday
  end

  module_function :parsedate
end

if __FILE__ == $0
  p Time.now.asctime
  p ParseDate.parsedate(Time.now.asctime)
end