Skip to content
Browse files

numerizer, time overflow

  • Loading branch information...
1 parent fc50735 commit 044fbd787e3de2509dd69d386df78aa6c2acfddb @mojombo mojombo committed Apr 1, 2007
View
5 History.txt
@@ -1,3 +1,8 @@
+= 0.2.0 2007-03-20
+
+* fixed time overflow issue
+* implemented numerizer, allowing the use of number words (e.g. five weeks ago) (thanks shalev!)
+
= 0.1.6 2006-01-15
* added 'weekend' support (eventualbuddha)
View
4 Manifest.txt
@@ -26,17 +26,19 @@ lib/chronic/repeaters/repeater_weekend.rb
lib/chronic/repeaters/repeater_year.rb
lib/chronic/scalar.rb
lib/chronic/separator.rb
-test/parse_numbers.rb
+lib/numerizer/numerizer.rb
test/suite.rb
test/test_Chronic.rb
test/test_Handler.rb
+test/test_Numerizer.rb
test/test_RepeaterDayName.rb
test/test_RepeaterFortnight.rb
test/test_RepeaterHour.rb
test/test_RepeaterMonth.rb
test/test_RepeaterMonthName.rb
test/test_RepeaterTime.rb
test/test_RepeaterWeek.rb
+test/test_RepeaterWeekend.rb
test/test_RepeaterYear.rb
test/test_Span.rb
test/test_Token.rb
View
28 Rakefile
@@ -7,35 +7,13 @@ require './lib/chronic.rb'
Hoe.new('chronic', Chronic::VERSION) do |p|
p.rubyforge_name = 'chronic'
p.summary = 'A natural language date parser'
+ p.author = 'Tom Preston-Werner'
+ p.email = 'tom@rubyisawesome.com'
p.description = p.paragraphs_of('README.txt', 2).join("\n\n")
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
p.need_tar = false
p.extra_deps = []
end
-# vim: syntax=Ruby
-
-__END__
-
-require 'rubygems'
-
-SPEC = Gem::Specification.new do |s|
- s.name = 'chronic'
- s.version = '0.1.5'
- s.author = 'Tom Preston-Werner'
- s.email = 'tom@rubyisawesome.com'
- s.homepage = 'http://chronic.rubyforge.org'
- s.platform = Gem::Platform::RUBY
- s.summary = "A natural language date parser"
- candidates = Dir["{lib,test}/**/*"]
- s.files = candidates.delete_if do |item|
- item.include?('.svn')
- end
- s.require_path = "lib"
- s.autorequire = "chronic"
- s.test_file = "test/suite.rb"
- s.has_rdoc = true
- s.extra_rdoc_files = ['README']
- s.rdoc_options << '--main' << 'README'
-end
+# vim: syntax=Ruby
View
52 lib/chronic.rb
@@ -7,6 +7,8 @@
#
#=============================================================================
+$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
+
require 'chronic/chronic'
require 'chronic/handlers'
@@ -33,8 +35,10 @@
require 'chronic/ordinal'
require 'chronic/separator'
+require 'numerizer/numerizer'
+
module Chronic
- VERSION = "0.1.6"
+ VERSION = "0.2.0"
def self.debug; false; end
end
@@ -44,4 +48,50 @@ def self.debug; false; end
def p(val)
p_orig val
puts
+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
View
6 lib/chronic/chronic.rb
@@ -101,6 +101,7 @@ def parse(text, specified_options = {})
# ordinals (third => 3rd)
def pre_normalize(text) #:nodoc:
normalized_text = text.to_s.downcase
+ normalized_text = numericize_numbers(normalized_text)
normalized_text.gsub!(/['"\.]/, '')
normalized_text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' }
normalized_text.gsub!(/\btoday\b/, 'this day')
@@ -118,15 +119,12 @@ def pre_normalize(text) #:nodoc:
normalized_text.gsub!(/\btonight\b/, 'this night')
normalized_text.gsub!(/(?=\w)([ap]m|oclock)\b/, ' \1')
normalized_text.gsub!(/\b(hence|after|from)\b/, 'future')
- normalized_text.gsub!(/\ba\b/, '1')
- normalized_text.gsub!(/\s+/, ' ')
- normalized_text = numericize_numbers(normalized_text)
normalized_text = numericize_ordinals(normalized_text)
end
# Convert number words to numbers (three => 3)
def numericize_numbers(text) #:nodoc:
- text
+ Numerizer.numerize(text)
end
# Convert ordinal words to numeric ordinals (third => 3rd)
View
24 lib/chronic/handlers.rb
@@ -214,17 +214,19 @@ def handle_srp(tokens, span, options) #:nodoc:
def handle_s_r_p(tokens, options) #:nodoc:
repeater = tokens[1].get_tag(Repeater)
- span =
- case true
- when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
- self.parse("this hour", :guess => false, :now => @now)
- when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
- self.parse("this minute", :guess => false, :now => @now)
- when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
- self.parse("this second", :guess => false, :now => @now)
- else
- raise(ChronicPain, "Invalid repeater: #{repeater.class}")
- end
+ # span =
+ # case true
+ # when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
+ # self.parse("this hour", :guess => false, :now => @now)
+ # when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
+ # self.parse("this minute", :guess => false, :now => @now)
+ # when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
+ # self.parse("this second", :guess => false, :now => @now)
+ # else
+ # raise(ChronicPain, "Invalid repeater: #{repeater.class}")
+ # end
+
+ span = self.parse("this second", :guess => false, :now => @now)
self.handle_srp(tokens, span, options)
end
View
6 lib/chronic/pointer.rb
@@ -10,9 +10,9 @@ def self.scan(tokens)
end
def self.scan_for_all(token)
- scanner = {/past/ => :past,
- /future/ => :future,
- /in/ => :future}
+ scanner = {/\bpast\b/ => :past,
+ /\bfuture\b/ => :future,
+ /\bin\b/ => :future}
scanner.keys.each do |scanner_item|
return self.new(scanner[scanner_item]) if scanner_item =~ token.word
end
View
12 lib/chronic/repeaters/repeater_day.rb
@@ -19,14 +19,14 @@ def this(pointer = :future)
case pointer
when :future
- day_begin = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
- day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
+ day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
when :past
- day_begin = Time.local(@now.year, @now.month, @now.day)
- day_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
+ day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
when :none
- day_begin = Time.local(@now.year, @now.month, @now.day)
- day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
end
Chronic::Span.new(day_begin, day_end)
View
2 lib/chronic/repeaters/repeater_day_name.rb
@@ -7,7 +7,7 @@ def next(pointer)
direction = pointer == :future ? 1 : -1
if !@current_day_start
- @current_day_start = Time.local(@now.year, @now.month, @now.day)
+ @current_day_start = Time.construct(@now.year, @now.month, @now.day)
@current_day_start += direction * DAY_SECONDS
day_num = symbol_to_number(@type)
View
16 lib/chronic/repeaters/repeater_day_portion.rb
@@ -28,27 +28,27 @@ def next(pointer)
full_day = 60 * 60 * 24
if !@current_span
- now_seconds = @now - Time.local(@now.year, @now.month, @now.day)
+ now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
if now_seconds < @range.begin
case pointer
when :future
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
when :past
- range_start = Time.local(@now.year, @now.month, @now.day) - full_day + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
end
elsif now_seconds > @range.end
case pointer
when :future
- range_start = Time.local(@now.year, @now.month, @now.day) + full_day + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
when :past
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
end
else
case pointer
when :future
- range_start = Time.local(@now.year, @now.month, @now.day) + full_day + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
when :past
- range_start = Time.local(@now.year, @now.month, @now.day) - full_day + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
end
end
@@ -66,7 +66,7 @@ def next(pointer)
def this(context = :future)
super
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
@current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
end
View
4 lib/chronic/repeaters/repeater_fortnight.rb
@@ -33,15 +33,15 @@ def this(pointer = :future)
case pointer
when :future
- this_fortnight_start = Time.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
+ this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
sunday_repeater.start = @now
sunday_repeater.this(:future)
this_sunday_span = sunday_repeater.this(:future)
this_fortnight_end = this_sunday_span.begin
Chronic::Span.new(this_fortnight_start, this_fortnight_end)
when :past
- this_fortnight_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
+ this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
sunday_repeater.start = @now
last_sunday_span = sunday_repeater.next(:past)
View
14 lib/chronic/repeaters/repeater_hour.rb
@@ -7,9 +7,9 @@ def next(pointer)
if !@current_hour_start
case pointer
when :future
- @current_hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
+ @current_hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
when :past
- @current_hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour - 1)
+ @current_hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour - 1)
end
else
direction = pointer == :future ? 1 : -1
@@ -24,13 +24,13 @@ def this(pointer = :future)
case pointer
when :future
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
- hour_end = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
+ hour_end = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
when :past
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour)
- hour_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour)
+ hour_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
when :none
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour)
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour)
hour_end = hour_begin + HOUR_SECONDS
end
View
8 lib/chronic/repeaters/repeater_minute.rb
@@ -15,13 +15,13 @@ def this(pointer = :future)
case pointer
when :future
minute_begin = @now
- minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
+ minute_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
when :past
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
+ minute_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
minute_end = @now
when :none
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
- minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
+ minute_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
+ minute_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
end
Chronic::Span.new(minute_begin, minute_end)
View
20 lib/chronic/repeaters/repeater_month.rb
@@ -6,27 +6,27 @@ def next(pointer)
super
if !@current_month_start
- @current_month_start = offset_by(Time.local(@now.year, @now.month), 1, pointer)
+ @current_month_start = offset_by(Time.construct(@now.year, @now.month), 1, pointer)
else
- @current_month_start = offset_by(Time.local(@current_month_start.year, @current_month_start.month), 1, pointer)
+ @current_month_start = offset_by(Time.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
end
- Chronic::Span.new(@current_month_start, Time.local(@current_month_start.year, @current_month_start.month + 1))
+ Chronic::Span.new(@current_month_start, Time.construct(@current_month_start.year, @current_month_start.month + 1))
end
def this(pointer = :future)
super
case pointer
when :future
- month_start = Time.local(@now.year, @now.month, @now.day + 1)
- month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
+ month_start = Time.construct(@now.year, @now.month, @now.day + 1)
+ month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
when :past
- month_start = Time.local(@now.year, @now.month)
- month_end = Time.local(@now.year, @now.month, @now.day)
+ month_start = Time.construct(@now.year, @now.month)
+ month_end = Time.construct(@now.year, @now.month, @now.day)
when :none
- month_start = Time.local(@now.year, @now.month)
- month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
+ month_start = Time.construct(@now.year, @now.month)
+ month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
end
Chronic::Span.new(month_start, month_end)
@@ -48,7 +48,7 @@ def offset_by(time, amount, pointer)
new_year += 1
new_month -= YEAR_MONTHS
end
- Time.local(new_year, new_month, time.day, time.hour, time.min, time.sec)
+ Time.construct(new_year, new_month, time.day, time.hour, time.min, time.sec)
end
def width
View
18 lib/chronic/repeaters/repeater_month_name.rb
@@ -9,30 +9,30 @@ def next(pointer)
case pointer
when :future
if @now.month < target_month
- @current_month_begin = Time.local(@now.year, target_month)
+ @current_month_begin = Time.construct(@now.year, target_month)
else @now.month > target_month
- @current_month_begin = Time.local(@now.year + 1, target_month)
+ @current_month_begin = Time.construct(@now.year + 1, target_month)
end
when :none
if @now.month <= target_month
- @current_month_begin = Time.local(@now.year, target_month)
+ @current_month_begin = Time.construct(@now.year, target_month)
else @now.month > target_month
- @current_month_begin = Time.local(@now.year + 1, target_month)
+ @current_month_begin = Time.construct(@now.year + 1, target_month)
end
when :past
if @now.month > target_month
- @current_month_begin = Time.local(@now.year, target_month)
+ @current_month_begin = Time.construct(@now.year, target_month)
else @now.month < target_month
- @current_month_begin = Time.local(@now.year - 1, target_month)
+ @current_month_begin = Time.construct(@now.year - 1, target_month)
end
end
@current_month_begin || raise("Current month should be set by now")
else
case pointer
when :future
- @current_month_begin = Time.local(@current_month_begin.year + 1, @current_month_begin.month)
+ @current_month_begin = Time.construct(@current_month_begin.year + 1, @current_month_begin.month)
when :past
- @current_month_begin = Time.local(@current_month_begin.year - 1, @current_month_begin.month)
+ @current_month_begin = Time.construct(@current_month_begin.year - 1, @current_month_begin.month)
end
end
@@ -47,7 +47,7 @@ def next(pointer)
next_month_month = cur_month_month + 1
end
- Chronic::Span.new(@current_month_begin, Time.local(next_month_year, next_month_month))
+ Chronic::Span.new(@current_month_begin, Time.construct(next_month_year, next_month_month))
end
def this(pointer = :future)
View
24 lib/chronic/repeaters/repeater_year.rb
@@ -6,31 +6,31 @@ def next(pointer)
if !@current_year_start
case pointer
when :future
- @current_year_start = Time.local(@now.year + 1)
+ @current_year_start = Time.construct(@now.year + 1)
when :past
- @current_year_start = Time.local(@now.year - 1)
+ @current_year_start = Time.construct(@now.year - 1)
end
else
diff = pointer == :future ? 1 : -1
- @current_year_start = Time.local(@current_year_start.year + diff)
+ @current_year_start = Time.construct(@current_year_start.year + diff)
end
- Chronic::Span.new(@current_year_start, Time.local(@current_year_start.year + 1))
+ Chronic::Span.new(@current_year_start, Time.construct(@current_year_start.year + 1))
end
def this(pointer = :future)
super
case pointer
when :future
- this_year_start = Time.local(@now.year, @now.month, @now.day) + Chronic::RepeaterDay::DAY_SECONDS
- this_year_end = Time.local(@now.year + 1, 1, 1)
+ this_year_start = Time.construct(@now.year, @now.month, @now.day) + Chronic::RepeaterDay::DAY_SECONDS
+ this_year_end = Time.construct(@now.year + 1, 1, 1)
when :past
- this_year_start = Time.local(@now.year, 1, 1)
- this_year_end = Time.local(@now.year, @now.month, @now.day)
+ this_year_start = Time.construct(@now.year, 1, 1)
+ this_year_end = Time.construct(@now.year, @now.month, @now.day)
when :none
- this_year_start = Time.local(@now.year, 1, 1)
- this_year_end = Time.local(@now.year + 1, 1, 1)
+ this_year_start = Time.construct(@now.year, 1, 1)
+ this_year_end = Time.construct(@now.year + 1, 1, 1)
end
Chronic::Span.new(this_year_start, this_year_end)
@@ -40,10 +40,10 @@ def offset(span, amount, pointer)
direction = pointer == :future ? 1 : -1
sb = span.begin
- new_begin = Time.local(sb.year + (amount * direction), sb.month, sb.day, sb.hour, sb.min, sb.sec)
+ new_begin = Time.construct(sb.year + (amount * direction), sb.month, sb.day, sb.hour, sb.min, sb.sec)
se = span.end
- new_end = Time.local(se.year + (amount * direction), se.month, se.day, se.hour, se.min, se.sec)
+ new_end = Time.construct(se.year + (amount * direction), se.month, se.day, se.hour, se.min, se.sec)
Chronic::Span.new(new_begin, new_end)
end
View
103 lib/numerizer/numerizer.rb
@@ -0,0 +1,103 @@
+require 'strscan'
+
+class Numerizer
+
+ DIRECT_NUMS = [
+ ['eleven', '11'],
+ ['twelve', '12'],
+ ['thirteen', '13'],
+ ['fourteen', '14'],
+ ['fifteen', '15'],
+ ['sixteen', '16'],
+ ['seventeen', '17'],
+ ['eighteen', '18'],
+ ['nineteen', '19'],
+ ['ninteen', '19'], # Common mis-spelling
+ ['zero', '0'],
+ ['one', '1'],
+ ['two', '2'],
+ ['three', '3'],
+ ['four(\W|$)', '4\1'], # The weird regex is so that it matches four but not fourty
+ ['five', '5'],
+ ['six(\W|$)', '6\1'],
+ ['seven(\W|$)', '7\1'],
+ ['eight(\W|$)', '8\1'],
+ ['nine(\W|$)', '9\1'],
+ ['ten', '10'],
+ ['\ba[\b^$]', '1'] # doesn't make sense for an 'a' at the end to be a 1
+ ]
+
+ TEN_PREFIXES = [ ['twenty', 20],
+ ['thirty', 30],
+ ['fourty', 40],
+ ['fifty', 50],
+ ['sixty', 60],
+ ['seventy', 70],
+ ['eighty', 80],
+ ['ninety', 90]
+ ]
+
+ BIG_PREFIXES = [ ['hundred', 100],
+ ['thousand', 1000],
+ ['million', 1_000_000],
+ ['billion', 1_000_000_000],
+ ['trillion', 1_000_000_000_000],
+ ]
+
+class << self
+ def numerize(string)
+ string = string.dup
+
+ # preprocess
+ string.gsub!(/ +|([^\d])-([^d])/, '\1 \2') # will mutilate hyphenated-words but shouldn't matter for date extraction
+ string.gsub!(/a half/, 'haAlf') # take the 'a' out so it doesn't turn into a 1, save the half for the end
+
+ # easy/direct replacements
+
+ DIRECT_NUMS.each do |dn|
+ string.gsub!(/#{dn[0]}/i, dn[1])
+ end
+
+ # ten, twenty, etc.
+
+ TEN_PREFIXES.each do |tp|
+ string.gsub!(/(?:#{tp[0]})( *\d(?=[^\d]|$))*/i) { (tp[1] + $1.to_i).to_s }
+ end
+
+ # hundreds, thousands, millions, etc.
+
+ BIG_PREFIXES.each do |bp|
+ string.gsub!(/(\d*) *#{bp[0]}/i) { (bp[1] * $1.to_i).to_s}
+ andition(string)
+ #combine_numbers(string) # Should to be more efficient way to do this
+ end
+
+ # fractional addition
+ # I'm not combining this with the previous block as using float addition complicates the strings
+ # (with extraneous .0's and such )
+ string.gsub!(/(\d+)(?: | and |-)*haAlf/i) { ($1.to_f + 0.5).to_s }
+
+ string
+ end
+
+private
+ def andition(string)
+ sc = StringScanner.new(string)
+ while(sc.scan_until(/(\d+)( | and )(\d+)(?=[^\w]|$)/i))
+ if sc[2] =~ /and/ || sc[1].size > sc[3].size
+ string[(sc.pos - sc.matched_size)..(sc.pos-1)] = (sc[1].to_i + sc[3].to_i).to_s
+ sc.reset
+ end
+ end
+ end
+
+# def combine_numbers(string)
+# sc = StringScanner.new(string)
+# while(sc.scan_until(/(\d+)(?: | and |-)(\d+)(?=[^\w]|$)/i))
+# string[(sc.pos - sc.matched_size)..(sc.pos-1)] = (sc[1].to_i + sc[2].to_i).to_s
+# sc.reset
+# end
+# end
+
+end
+end
View
14 test/parse_numbers.rb → test/test_Numerizer.rb
@@ -1,11 +1,10 @@
-__END__
-
require 'test/unit'
+require 'chronic'
class ParseNumbersTest < Test::Unit::TestCase
- def test_parse
- strings = {1 => 'one',
+ def test_straight_parsing
+ strings = { 1 => 'one',
5 => 'five',
10 => 'ten',
11 => 'eleven',
@@ -24,7 +23,7 @@ def test_parse
100 => 'a hundred',
100 => 'one hundred',
150 => 'one hundred and fifty',
- 150 => 'one fifty',
+ # 150 => 'one fifty',
200 => 'two-hundred',
500 => '5 hundred',
999 => 'nine hundred and ninety nine',
@@ -40,11 +39,10 @@ def test_parse
1_000_000 => 'one million',
1_250_007 => 'one million two hundred fifty thousand and seven',
1_000_000_000 => 'one billion',
- 1_000_000_001 => 'one billion and one'}
+ 1_000_000_001 => 'one billion and one' }
strings.keys.sort.each do |key|
- assert_equal key, JW::NumberMagick.convert(strings[key])
+ assert_equal key, Numerizer.numerize(strings[key]).to_i
end
end
-
end
View
50 test/test_Time.rb
@@ -0,0 +1,50 @@
+require 'chronic'
+require 'test/unit'
+
+class TestTime < Test::Unit::TestCase
+
+ def setup
+ end
+
+ def test_normal
+ assert_equal Time.local(2006, 1, 2, 0, 0, 0), Time.construct(2006, 1, 2, 0, 0, 0)
+ assert_equal Time.local(2006, 1, 2, 3, 0, 0), Time.construct(2006, 1, 2, 3, 0, 0)
+ assert_equal Time.local(2006, 1, 2, 3, 4, 0), Time.construct(2006, 1, 2, 3, 4, 0)
+ assert_equal Time.local(2006, 1, 2, 3, 4, 5), Time.construct(2006, 1, 2, 3, 4, 5)
+ end
+
+ def test_second_overflow
+ assert_equal Time.local(2006, 1, 1, 0, 1, 30), Time.construct(2006, 1, 1, 0, 0, 90)
+ assert_equal Time.local(2006, 1, 1, 0, 5, 0), Time.construct(2006, 1, 1, 0, 0, 300)
+ end
+
+ def test_minute_overflow
+ assert_equal Time.local(2006, 1, 1, 1, 30), Time.construct(2006, 1, 1, 0, 90)
+ assert_equal Time.local(2006, 1, 1, 5), Time.construct(2006, 1, 1, 0, 300)
+ end
+
+ def test_hour_overflow
+ assert_equal Time.local(2006, 1, 2, 12), Time.construct(2006, 1, 1, 36)
+ assert_equal Time.local(2006, 1, 7), Time.construct(2006, 1, 1, 144)
+ end
+
+ def test_day_overflow
+ assert_equal Time.local(2006, 2, 1), Time.construct(2006, 1, 32)
+ assert_equal Time.local(2006, 3, 5), Time.construct(2006, 2, 33)
+ assert_equal Time.local(2004, 3, 4), Time.construct(2004, 2, 33)
+ assert_equal Time.local(2000, 3, 5), Time.construct(2000, 2, 33)
+
+ assert_nothing_raised do
+ Time.construct(2006, 1, 56)
+ end
+
+ assert_raise(RuntimeError) do
+ Time.construct(2006, 1, 57)
+ end
+ end
+
+ def test_month_overflow
+ assert_equal Time.local(2006, 1), Time.construct(2005, 13)
+ assert_equal Time.local(2005, 12), Time.construct(2000, 72)
+ end
+end
View
326 test/test_parsing.rb
@@ -2,514 +2,520 @@
require 'test/unit'
class TestParsing < Test::Unit::TestCase
+ # Wed Aug 16 14:00:00 UTC 2006
+ TIME_2006_08_16_14_00_00 = Time.local(2006, 8, 16, 14, 0, 0, 0)
def setup
- # Wed Aug 16 14:00:00 UTC 2006
- @time_2006_08_16_14_00_00 = Time.local(2006, 8, 16, 14, 0, 0, 0)
- @time_2006_08_16_03_00_00 = Time.local(2006, 8, 16, 3, 0, 0, 0)
+ @time_2006_08_16_14_00_00 = TIME_2006_08_16_14_00_00
end
- def test__parse_guess_dates
+ def test_parse_guess_dates
# rm_sd
- time = Chronic.parse("may 27", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 27")
assert_equal Time.local(2007, 5, 27, 12), time
- time = Chronic.parse("may 28", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 28", :context => :past)
assert_equal Time.local(2006, 5, 28, 12), time
- time = Chronic.parse("may 28 5pm", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 28 5pm", :context => :past)
assert_equal Time.local(2006, 5, 28, 17), time
- time = Chronic.parse("may 28 at 5pm", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 28 at 5pm", :context => :past)
assert_equal Time.local(2006, 5, 28, 17), time
- time = Chronic.parse("may 28 at 5:32.19pm", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 28 at 5:32.19pm", :context => :past)
assert_equal Time.local(2006, 5, 28, 17, 32, 19), time
# rm_od
- time = Chronic.parse("may 27th", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 27th")
assert_equal Time.local(2007, 5, 27, 12), time
- time = Chronic.parse("may 27th", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 27th", :context => :past)
assert_equal Time.local(2006, 5, 27, 12), time
- time = Chronic.parse("may 27th 5:00 pm", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 27th 5:00 pm", :context => :past)
assert_equal Time.local(2006, 5, 27, 17), time
- time = Chronic.parse("may 27th at 5pm", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("may 27th at 5pm", :context => :past)
assert_equal Time.local(2006, 5, 27, 17), time
- time = Chronic.parse("may 27th at 5", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("may 27th at 5", :ambiguous_time_range => :none)
assert_equal Time.local(2007, 5, 27, 5), time
# rm_sy
- time = Chronic.parse("June 1979", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("June 1979")
assert_equal Time.local(1979, 6, 16, 0), time
- time = Chronic.parse("dec 79", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("dec 79")
assert_equal Time.local(1979, 12, 16, 12), time
# rm_sd_sy
- time = Chronic.parse("jan 3 2010", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("jan 3 2010")
assert_equal Time.local(2010, 1, 3, 12), time
- time = Chronic.parse("jan 3 2010 midnight", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("jan 3 2010 midnight")
assert_equal Time.local(2010, 1, 4, 0), time
- time = Chronic.parse("jan 3 2010 at midnight", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("jan 3 2010 at midnight")
assert_equal Time.local(2010, 1, 4, 0), time
- time = Chronic.parse("jan 3 2010 at 4", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("jan 3 2010 at 4", :ambiguous_time_range => :none)
assert_equal Time.local(2010, 1, 3, 4), time
- #time = Chronic.parse("January 12, '00", :now => @time_2006_08_16_14_00_00)
+ #time = parse_now("January 12, '00")
#assert_equal Time.local(2000, 1, 12, 12), time
- time = Chronic.parse("may 27 79", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 27 79")
assert_equal Time.local(1979, 5, 27, 12), time
- time = Chronic.parse("may 27 79 4:30", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 27 79 4:30")
assert_equal Time.local(1979, 5, 27, 16, 30), time
- time = Chronic.parse("may 27 79 at 4:30", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("may 27 79 at 4:30", :ambiguous_time_range => :none)
assert_equal Time.local(1979, 5, 27, 4, 30), time
# sd_rm_sy
- time = Chronic.parse("3 jan 2010", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 jan 2010")
assert_equal Time.local(2010, 1, 3, 12), time
- time = Chronic.parse("3 jan 2010 4pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 jan 2010 4pm")
assert_equal Time.local(2010, 1, 3, 16), time
# sm_sd_sy
- time = Chronic.parse("5/27/1979", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("5/27/1979")
assert_equal Time.local(1979, 5, 27, 12), time
- time = Chronic.parse("5/27/1979 4am", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("5/27/1979 4am")
assert_equal Time.local(1979, 5, 27, 4), time
# sd_sm_sy
- time = Chronic.parse("27/5/1979", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("27/5/1979")
assert_equal Time.local(1979, 5, 27, 12), time
- time = Chronic.parse("27/5/1979 @ 0700", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("27/5/1979 @ 0700")
assert_equal Time.local(1979, 5, 27, 7), time
# sm_sy
- time = Chronic.parse("05/06", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("05/06")
assert_equal Time.local(2006, 5, 16, 12), time
- time = Chronic.parse("12/06", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("12/06")
assert_equal Time.local(2006, 12, 16, 12), time
- time = Chronic.parse("13/06", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("13/06")
assert_equal nil, time
# sy_sm_sd
- time = Chronic.parse("2000-1-1", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2000-1-1")
assert_equal Time.local(2000, 1, 1, 12), time
- time = Chronic.parse("2006-08-20", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20")
assert_equal Time.local(2006, 8, 20, 12), time
- time = Chronic.parse("2006-08-20 7pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20 7pm")
assert_equal Time.local(2006, 8, 20, 19), time
- time = Chronic.parse("2006-08-20 03:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20 03:00")
assert_equal Time.local(2006, 8, 20, 3), time
- time = Chronic.parse("2006-08-20 03:30:30", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20 03:30:30")
assert_equal Time.local(2006, 8, 20, 3, 30, 30), time
- time = Chronic.parse("2006-08-20 15:30:30", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20 15:30:30")
assert_equal Time.local(2006, 8, 20, 15, 30, 30), time
- time = Chronic.parse("2006-08-20 15:30.30", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2006-08-20 15:30.30")
assert_equal Time.local(2006, 8, 20, 15, 30, 30), time
# rm_sd_rt
- #time = Chronic.parse("jan 5 13:00", :now => @time_2006_08_16_14_00_00)
+ #time = parse_now("jan 5 13:00")
#assert_equal Time.local(2007, 1, 5, 13), time
# due to limitations of the Time class, these don't work
- time = Chronic.parse("may 40", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 40")
assert_equal nil, time
- time = Chronic.parse("may 27 40", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("may 27 40")
assert_equal nil, time
- time = Chronic.parse("1800-08-20", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("1800-08-20")
assert_equal nil, time
end
def test_parse_guess_r
- time = Chronic.parse("friday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("friday")
assert_equal Time.local(2006, 8, 18, 12), time
- time = Chronic.parse("5", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("5")
assert_equal Time.local(2006, 8, 16, 17), time
- time = Chronic.parse("5", :now => @time_2006_08_16_03_00_00, :ambiguous_time_range => :none)
+ time = Chronic.parse("5", :now => Time.local(2006, 8, 16, 3, 0, 0, 0), :ambiguous_time_range => :none)
assert_equal Time.local(2006, 8, 16, 5), time
- time = Chronic.parse("13:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("13:00")
assert_equal Time.local(2006, 8, 17, 13), time
- time = Chronic.parse("13:45", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("13:45")
assert_equal Time.local(2006, 8, 17, 13, 45), time
- time = Chronic.parse("november", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("november")
assert_equal Time.local(2006, 11, 16), time
end
def test_parse_guess_rr
- time = Chronic.parse("friday 13:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("friday 13:00")
assert_equal Time.local(2006, 8, 18, 13), time
- time = Chronic.parse("monday 4:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("monday 4:00")
assert_equal Time.local(2006, 8, 21, 16), time
- time = Chronic.parse("sat 4:00", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("sat 4:00", :ambiguous_time_range => :none)
assert_equal Time.local(2006, 8, 19, 4), time
- time = Chronic.parse("sunday 4:20", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("sunday 4:20", :ambiguous_time_range => :none)
assert_equal Time.local(2006, 8, 20, 4, 20), time
- time = Chronic.parse("4 pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("4 pm")
assert_equal Time.local(2006, 8, 16, 16), time
- time = Chronic.parse("4 am", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("4 am", :ambiguous_time_range => :none)
assert_equal Time.local(2006, 8, 16, 4), time
- time = Chronic.parse("4:00 in the morning", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("4:00 in the morning")
assert_equal Time.local(2006, 8, 16, 4), time
- time = Chronic.parse("november 4", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("november 4")
assert_equal Time.local(2006, 11, 4, 12), time
- time = Chronic.parse("aug 24", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("aug 24")
assert_equal Time.local(2006, 8, 24, 12), time
end
def test_parse_guess_rrr
- time = Chronic.parse("friday 1 pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("friday 1 pm")
assert_equal Time.local(2006, 8, 18, 13), time
- time = Chronic.parse("friday 11 at night", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("friday 11 at night")
assert_equal Time.local(2006, 8, 18, 23), time
- time = Chronic.parse("friday 11 in the evening", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("friday 11 in the evening")
assert_equal Time.local(2006, 8, 18, 23), time
- time = Chronic.parse("sunday 6am", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("sunday 6am")
assert_equal Time.local(2006, 8, 20, 6), time
end
def test_parse_guess_gr
# year
- time = Chronic.parse("this year", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this year")
assert_equal Time.local(2006, 10, 24, 12, 30), time
- time = Chronic.parse("this year", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this year", :context => :past)
assert_equal Time.local(2006, 4, 24, 12, 30), time
# month
- time = Chronic.parse("this month", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this month")
assert_equal Time.local(2006, 8, 24, 12), time
- time = Chronic.parse("this month", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this month", :context => :past)
assert_equal Time.local(2006, 8, 8, 12), time
+ time = Chronic.parse("next month", :now => Time.local(2006, 11, 15))
+ assert_equal Time.local(2006, 12, 16, 12), time
+
# month name
- time = Chronic.parse("last november", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last november")
assert_equal Time.local(2005, 11, 16), time
# fortnight
- time = Chronic.parse("this fortnight", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this fortnight")
assert_equal Time.local(2006, 8, 21, 19, 30), time
- time = Chronic.parse("this fortnight", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this fortnight", :context => :past)
assert_equal Time.local(2006, 8, 14, 19), time
# week
- time = Chronic.parse("this week", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this week")
assert_equal Time.local(2006, 8, 18, 7, 30), time
- time = Chronic.parse("this week", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this week", :context => :past)
assert_equal Time.local(2006, 8, 14, 19), time
# weekend
- time = Chronic.parse("this weekend", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this weekend")
assert_equal Time.local(2006, 8, 20), time
- time = Chronic.parse("this weekend", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this weekend", :context => :past)
assert_equal Time.local(2006, 8, 13), time
- time = Chronic.parse("last weekend", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last weekend")
assert_equal Time.local(2006, 8, 13), time
# day
- time = Chronic.parse("this day", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this day")
assert_equal Time.local(2006, 8, 16, 19, 30), time
- time = Chronic.parse("this day", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this day", :context => :past)
assert_equal Time.local(2006, 8, 16, 7), time
- time = Chronic.parse("today", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("today")
assert_equal Time.local(2006, 8, 16, 19, 30), time
- time = Chronic.parse("yesterday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("yesterday")
assert_equal Time.local(2006, 8, 15, 12), time
- time = Chronic.parse("tomorrow", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("tomorrow")
assert_equal Time.local(2006, 8, 17, 12), time
# day name
- time = Chronic.parse("this tuesday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this tuesday")
assert_equal Time.local(2006, 8, 22, 12), time
- time = Chronic.parse("next tuesday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("next tuesday")
assert_equal Time.local(2006, 8, 22, 12), time
- time = Chronic.parse("last tuesday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last tuesday")
assert_equal Time.local(2006, 8, 15, 12), time
- time = Chronic.parse("this wed", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this wed")
assert_equal Time.local(2006, 8, 23, 12), time
- time = Chronic.parse("next wed", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("next wed")
assert_equal Time.local(2006, 8, 23, 12), time
- time = Chronic.parse("last wed", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last wed")
assert_equal Time.local(2006, 8, 9, 12), time
# day portion
- time = Chronic.parse("this morning", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this morning")
assert_equal Time.local(2006, 8, 16, 9), time
- time = Chronic.parse("tonight", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("tonight")
assert_equal Time.local(2006, 8, 16, 22), time
# second
- time = Chronic.parse("this second", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this second")
assert_equal Time.local(2006, 8, 16, 14), time
- time = Chronic.parse("this second", :now => @time_2006_08_16_14_00_00, :context => :past)
+ time = parse_now("this second", :context => :past)
assert_equal Time.local(2006, 8, 16, 14), time
- time = Chronic.parse("next second", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("next second")
assert_equal Time.local(2006, 8, 16, 14, 0, 1), time
- time = Chronic.parse("last second", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last second")
assert_equal Time.local(2006, 8, 16, 13, 59, 59), time
end
def test_parse_guess_grr
- time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("yesterday at 4:00")
assert_equal Time.local(2006, 8, 15, 16), time
- time = Chronic.parse("today at 9:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("today at 9:00")
assert_equal Time.local(2006, 8, 16, 9), time
- time = Chronic.parse("today at 2100", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("today at 2100")
assert_equal Time.local(2006, 8, 16, 21), time
- time = Chronic.parse("this day at 0900", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this day at 0900")
assert_equal Time.local(2006, 8, 16, 9), time
- time = Chronic.parse("tomorrow at 0900", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("tomorrow at 0900")
assert_equal Time.local(2006, 8, 17, 9), time
- time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
+ time = parse_now("yesterday at 4:00", :ambiguous_time_range => :none)
assert_equal Time.local(2006, 8, 15, 4), time
- time = Chronic.parse("last friday at 4:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last friday at 4:00")
assert_equal Time.local(2006, 8, 11, 16), time
- time = Chronic.parse("next wed 4:00", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("next wed 4:00")
assert_equal Time.local(2006, 8, 23, 16), time
- time = Chronic.parse("yesterday afternoon", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("yesterday afternoon")
assert_equal Time.local(2006, 8, 15, 15), time
- time = Chronic.parse("last week tuesday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("last week tuesday")
assert_equal Time.local(2006, 8, 8, 12), time
end
def test_parse_guess_grrr
- time = Chronic.parse("today at 6:00pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("today at 6:00pm")
assert_equal Time.local(2006, 8, 16, 18), time
- time = Chronic.parse("today at 6:00am", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("today at 6:00am")
assert_equal Time.local(2006, 8, 16, 6), time
- time = Chronic.parse("this day 1800", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("this day 1800")
assert_equal Time.local(2006, 8, 16, 18), time
- time = Chronic.parse("yesterday at 4:00pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("yesterday at 4:00pm")
assert_equal Time.local(2006, 8, 15, 16), time
end
def test_parse_guess_rgr
- time = Chronic.parse("afternoon yesterday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("afternoon yesterday")
assert_equal Time.local(2006, 8, 15, 15), time
- time = Chronic.parse("tuesday last week", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("tuesday last week")
assert_equal Time.local(2006, 8, 8, 12), time
end
def test_parse_guess_s_r_p
# past
- time = Chronic.parse("3 years ago", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2003, 8, 16, 14, 30, 30), time
+ time = parse_now("3 years ago")
+ assert_equal Time.local(2003, 8, 16, 14), time
- time = Chronic.parse("1 month ago", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2006, 7, 16, 14, 30, 30), time
+ time = parse_now("1 month ago")
+ assert_equal Time.local(2006, 7, 16, 14), time
- time = Chronic.parse("1 fortnight ago", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2006, 8, 2, 14, 30, 30), time
+ time = parse_now("1 fortnight ago")
+ assert_equal Time.local(2006, 8, 2, 14), time
- time = Chronic.parse("2 fortnights ago", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2006, 7, 19, 14, 30, 30), time
+ time = parse_now("2 fortnights ago")
+ assert_equal Time.local(2006, 7, 19, 14), time
- time = Chronic.parse("3 weeks ago", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2006, 7, 26, 14, 30, 30), time
+ time = parse_now("3 weeks ago")
+ assert_equal Time.local(2006, 7, 26, 14), time
- time = Chronic.parse("2 weekends ago", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2 weekends ago")
assert_equal Time.local(2006, 8, 5), time
- time = Chronic.parse("3 days ago", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 days ago")
assert_equal Time.local(2006, 8, 13, 14), time
- #time = Chronic.parse("1 monday ago", :now => @time_2006_08_16_14_00_00)
+ #time = parse_now("1 monday ago")
#assert_equal Time.local(2006, 8, 14, 12), time
- time = Chronic.parse("5 mornings ago", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("5 mornings ago")
assert_equal Time.local(2006, 8, 12, 9), time
- time = Chronic.parse("7 hours ago", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("7 hours ago")
assert_equal Time.local(2006, 8, 16, 7), time
- time = Chronic.parse("3 minutes ago", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 minutes ago")
assert_equal Time.local(2006, 8, 16, 13, 57), time
- time = Chronic.parse("20 seconds before now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("20 seconds before now")
assert_equal Time.local(2006, 8, 16, 13, 59, 40), time
# future
- time = Chronic.parse("3 years from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 years from now")
assert_equal Time.local(2009, 8, 16, 14, 0, 0), time
- time = Chronic.parse("6 months hence", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2007, 2, 16, 14, 30, 30), time
+ time = parse_now("6 months hence")
+ assert_equal Time.local(2007, 2, 16, 14), time
- time = Chronic.parse("3 fortnights hence", :now => @time_2006_08_16_14_00_00)
- assert_equal Time.local(2006, 9, 27, 14, 30, 30), time
+ time = parse_now("3 fortnights hence")
+ assert_equal Time.local(2006, 9, 27, 14), time
- time = Chronic.parse("1 week from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("1 week from now")
assert_equal Time.local(2006, 8, 23, 14, 0, 0), time
- time = Chronic.parse("1 weekend from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("1 weekend from now")
assert_equal Time.local(2006, 8, 19), time
- time = Chronic.parse("2 weekends from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2 weekends from now")
assert_equal Time.local(2006, 8, 26), time
- time = Chronic.parse("1 day hence", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("1 day hence")
assert_equal Time.local(2006, 8, 17, 14), time
- time = Chronic.parse("5 mornings hence", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("5 mornings hence")
assert_equal Time.local(2006, 8, 21, 9), time
- time = Chronic.parse("1 hour from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("1 hour from now")
assert_equal Time.local(2006, 8, 16, 15), time
- time = Chronic.parse("20 minutes hence", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("20 minutes hence")
assert_equal Time.local(2006, 8, 16, 14, 20), time
- time = Chronic.parse("20 seconds from now", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("20 seconds from now")
assert_equal Time.local(2006, 8, 16, 14, 0, 20), time
+
+ time = Chronic.parse("2 months ago", :now => Time.parse("2007-03-07 23:30"))
+ assert_equal Time.local(2007, 1, 7, 23, 30), time
end
def test_parse_guess_p_s_r
- time = Chronic.parse("in 3 hours", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("in 3 hours")
assert_equal Time.local(2006, 8, 16, 17), time
end
def test_parse_guess_s_r_p_a
# past
- time = Chronic.parse("3 years ago tomorrow", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 years ago tomorrow")
assert_equal Time.local(2003, 8, 17, 12), time
- time = Chronic.parse("3 years ago this friday", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 years ago this friday")
assert_equal Time.local(2003, 8, 18, 12), time
- time = Chronic.parse("3 months ago saturday at 5:00 pm", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3 months ago saturday at 5:00 pm")
assert_equal Time.local(2006, 5, 19, 17), time
- time = Chronic.parse("2 days from this second", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("2 days from this second")
assert_equal Time.local(2006, 8, 18, 14), time
- time = Chronic.parse("7 hours before tomorrow at midnight", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("7 hours before tomorrow at midnight")
assert_equal Time.local(2006, 8, 17, 17), time
# future
end
def test_parse_guess_o_r_s_r
- time = Chronic.parse("3rd wednesday in november", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3rd wednesday in november")
assert_equal Time.local(2006, 11, 15, 12), time
- time = Chronic.parse("10th wednesday in november", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("10th wednesday in november")
assert_equal nil, time
end
def test_parse_guess_o_r_g_r
- time = Chronic.parse("3rd month next year", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3rd month next year")
assert_equal Time.local(2007, 3, 16, 12, 30), time
- time = Chronic.parse("3rd thursday this september", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("3rd thursday this september")
assert_equal Time.local(2006, 9, 21, 12), time
- time = Chronic.parse("4th day last week", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("4th day last week")
assert_equal Time.local(2006, 8, 9, 12), time
end
def test_parse_guess_nonsense
- time = Chronic.parse("some stupid nonsense", :now => @time_2006_08_16_14_00_00)
+ time = parse_now("some stupid nonsense")
assert_equal nil, time
end
def test_parse_span
- span = Chronic.parse("friday", :now => @time_2006_08_16_14_00_00, :guess => false)
+ span = parse_now("friday", :guess => false)
assert_equal Time.local(2006, 8, 18), span.begin
assert_equal Time.local(2006, 8, 19), span.end
- span = Chronic.parse("november", :now => @time_2006_08_16_14_00_00, :guess => false)
+ span = parse_now("november", :guess => false)
assert_equal Time.local(2006, 11), span.begin
assert_equal Time.local(2006, 12), span.end
@@ -518,6 +524,18 @@ def test_parse_span
assert_equal Time.local(2006, 8, 21), span.end
end
+ def test_parse_words
+ assert_equal parse_now("33 days from now"), parse_now("thirty-three days from now")
+ assert_equal parse_now("2867532 seconds from now"), parse_now("two million eight hundred and sixty seven thousand five hundred and thirty two seconds from now")
+ assert_equal parse_now("may 10th"), parse_now("may tenth")
+ end
+
+ def test_parse_only_complete_pointers
+ assert_equal parse_now("eat pasty buns today at 2pm"), @time_2006_08_16_14_00_00
+ assert_equal parse_now("futuristically speaking today at 2pm"), @time_2006_08_16_14_00_00
+ assert_equal parse_now("meeting today at 2pm"), @time_2006_08_16_14_00_00
+ end
+
def test_argument_validation
assert_raise(Chronic::InvalidArgumentException) do
time = Chronic.parse("may 27", :foo => :bar)
@@ -528,4 +546,8 @@ def test_argument_validation
end
end
+ private
+ def parse_now(string, options={})
+ Chronic.parse(string, {:now => TIME_2006_08_16_14_00_00 }.merge(options))
+ end
end

0 comments on commit 044fbd7

Please sign in to comment.
Something went wrong with that request. Please try again.