public
Fork of mojombo/chronic
Description: "Chronic is a pure Ruby natural language date parser." + improvements, corrections, speedups, and additions
Homepage: http://chronic.rubyforge.org
Clone URL: git://github.com/jf/chronic.git
jf (author)
Mon Apr 14 09:48:15 -0700 2008
commit  8a931393e9499795a5c53a8fb8208842643cb38b
tree    435714738fc1c79e0df2a8aa548267b982708b47
parent  7a1ed038fdc972bb1b42096d39bc70628e064426
chronic / lib / chronic.rb
100644 133 lines (114 sloc) 3.652 kb
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#=============================================================================
#
# Name: Chronic
# Author: Tom Preston-Werner
# Purpose: Parse natural language dates and times into Time or
# Chronic::Span objects
#
#=============================================================================
 
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
 
require 'time'
 
require 'chronic/chronic'
require 'chronic/handlers'
 
require 'chronic/repeater'
require 'chronic/repeaters/repeater_year'
require 'chronic/repeaters/repeater_season'
require 'chronic/repeaters/repeater_season_name'
require 'chronic/repeaters/repeater_month'
require 'chronic/repeaters/repeater_month_name'
require 'chronic/repeaters/repeater_fortnight'
require 'chronic/repeaters/repeater_week'
require 'chronic/repeaters/repeater_weekend'
require 'chronic/repeaters/repeater_weekday'
require 'chronic/repeaters/repeater_day'
require 'chronic/repeaters/repeater_day_name'
require 'chronic/repeaters/repeater_day_portion'
require 'chronic/repeaters/repeater_hour'
require 'chronic/repeaters/repeater_minute'
require 'chronic/repeaters/repeater_second'
require 'chronic/repeaters/repeater_time'
 
require 'chronic/grabber'
require 'chronic/pointer'
require 'chronic/scalar'
require 'chronic/ordinal'
require 'chronic/separator'
require 'chronic/time_zone'
 
require 'numerizer/numerizer'
 
module Chronic
  VERSION = "0.2.4"
  
  class << self
    attr_accessor :debug
  end
  
  self.debug = false
end
 
alias p_orig p
 
def p(val)
  p_orig val
  puts
end
 
# class Time
# def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
# # extra_seconds = second > 60 ? second - 60 : 0
# # extra_minutes = minute > 59 ? minute - 59 : 0
# # extra_hours = hour > 23 ? hour - 23 : 0
# # extra_days = day >
#
# if month > 12
# if month % 12 == 0
# year += (month - 12) / 12
# month = 12
# else
# year += month / 12
# month = month % 12
# end
# end
#
# base = Time.local(year, month)
# puts base
# offset = ((day - 1) * 24 * 60 * 60) + (hour * 60 * 60) + (minute * 60) + second
# puts offset.to_s
# date = base + offset
# puts date
# date
# end
# end
 
class Time
  def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
    if second >= 60
      minute += second / 60
      second = second % 60
    end
    
    if minute >= 60
      hour += minute / 60
      minute = minute % 60
    end
    
    if hour >= 24
      day += hour / 24
      hour = hour % 24
    end
    
    # determine if there is a day overflow. this is complicated by our crappy calendar
    # system (non-constant number of days per month)
    day <= 56 || raise("day must be no more than 56 (makes month resolution easier)")
    if day > 28
      # no month ever has fewer than 28 days, so only do this if necessary
      leap_year = (year % 4 == 0) && !(year % 100 == 0)
      leap_year_month_days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      common_year_month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
      days_this_month = leap_year ? leap_year_month_days[month - 1] : common_year_month_days[month - 1]
      if day > days_this_month
        month += day / days_this_month
        day = day % days_this_month
      end
    end
    
    if month > 12
      if month % 12 == 0
        year += (month - 12) / 12
        month = 12
      else
        year += month / 12
        month = month % 12
      end
    end
    
    Time.local(year, month, day, hour, minute, second)
  end
end