runt 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +153 -125
 - data/LICENSE.txt +43 -43
 - data/README +106 -100
 - data/Rakefile +122 -122
 - data/TODO +13 -13
 - data/doc/tutorial_schedule.rdoc +393 -393
 - data/doc/tutorial_sugar.rdoc +143 -0
 - data/doc/tutorial_te.rdoc +190 -190
 - data/examples/payment_report.rb +59 -0
 - data/examples/payment_reporttest.rb +49 -0
 - data/examples/reminder.rb +63 -63
 - data/lib/runt.rb +237 -219
 - data/lib/runt/daterange.rb +74 -74
 - data/lib/runt/dprecision.rb +150 -141
 - data/lib/runt/expressionbuilder.rb +65 -0
 - data/lib/runt/pdate.rb +165 -153
 - data/lib/runt/schedule.rb +88 -88
 - data/lib/runt/sugar.rb +171 -0
 - data/lib/runt/temporalexpression.rb +789 -777
 - data/setup.rb +1331 -1331
 - data/site/blue-robot3.css +131 -131
 - data/site/dcl-small.gif +0 -0
 - data/site/index.html +72 -94
 - data/site/runt-logo.gif +0 -0
 - data/site/runt-logo.psd +0 -0
 - data/test/aftertetest.rb +31 -0
 - data/test/beforetetest.rb +31 -0
 - data/test/daterangetest.rb +89 -89
 - data/test/dprecisiontest.rb +58 -55
 - data/test/expressionbuildertest.rb +64 -0
 - data/test/icalendartest.rb +621 -41
 - data/test/pdatetest.rb +147 -117
 - data/test/redaytest.rb +10 -0
 - data/test/reyeartest.rb +99 -98
 - data/test/runttest.rb +98 -101
 - data/test/scheduletest.rb +148 -148
 - data/test/sugartest.rb +104 -0
 - data/test/temporalexpressiontest.rb +76 -76
 - metadata +112 -95
 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'runt'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class Report
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
              attr_reader :schedule
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(schedule)
         
     | 
| 
      
 10 
     | 
    
         
            +
                @schedule = schedule
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              def list(range)
         
     | 
| 
      
 13 
     | 
    
         
            +
                result = {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                range.each do |dt|
         
     | 
| 
      
 15 
     | 
    
         
            +
                  events = @schedule.events(dt)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  result[dt]=events unless events.empty?
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
                result
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            class Payment < Runt::Event
         
     | 
| 
      
 23 
     | 
    
         
            +
              attr_accessor :amount
         
     | 
| 
      
 24 
     | 
    
         
            +
              def initialize(id, amount)
         
     | 
| 
      
 25 
     | 
    
         
            +
                super(id)
         
     | 
| 
      
 26 
     | 
    
         
            +
                @amount = amount
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            if __FILE__ == $0
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              schedule = Schedule.new
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              # Gas payment on the first Wednesday of every month
         
     | 
| 
      
 38 
     | 
    
         
            +
              gas_payment = Payment.new("Gas", 234)
         
     | 
| 
      
 39 
     | 
    
         
            +
              gas_expr = DIMonth.new(First, Wednesday)
         
     | 
| 
      
 40 
     | 
    
         
            +
              schedule.add(gas_payment, gas_expr)
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              # Insurance payment every year on January 7th
         
     | 
| 
      
 43 
     | 
    
         
            +
              insurance_payment = Payment.new("Insurance", 345)
         
     | 
| 
      
 44 
     | 
    
         
            +
              insurance_expr = REYear.new(1, 7, 1, 7)
         
     | 
| 
      
 45 
     | 
    
         
            +
              schedule.add(insurance_payment, insurance_expr)
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              # Run a report
         
     | 
| 
      
 48 
     | 
    
         
            +
              report = Report.new(schedule)
         
     | 
| 
      
 49 
     | 
    
         
            +
              result = report.list(PDate.day(2008, 1, 1)..PDate.day(2008,1,31))
         
     | 
| 
      
 50 
     | 
    
         
            +
              result.keys.sort.each do |dt|
         
     | 
| 
      
 51 
     | 
    
         
            +
                unless result[dt].empty? then
         
     | 
| 
      
 52 
     | 
    
         
            +
                  print "#{dt.ctime} - "
         
     | 
| 
      
 53 
     | 
    
         
            +
                  result[dt].each do |event|
         
     | 
| 
      
 54 
     | 
    
         
            +
            	puts "#{event.id}, $#{event.amount}"
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'runt'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'payment_report'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class ReportTest < Test::Unit::TestCase
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 12 
     | 
    
         
            +
                @schedule = Schedule.new
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # Gas payment on the first Wednesday of every month
         
     | 
| 
      
 15 
     | 
    
         
            +
                @gas_payment = Payment.new("Gas", 234)
         
     | 
| 
      
 16 
     | 
    
         
            +
                @gas_expr = DIMonth.new(First, Wednesday)
         
     | 
| 
      
 17 
     | 
    
         
            +
                @schedule.add(@gas_payment, @gas_expr)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Insurance payment every year on January 7th
         
     | 
| 
      
 20 
     | 
    
         
            +
                @insurance_payment = Payment.new("Insurance", 345)
         
     | 
| 
      
 21 
     | 
    
         
            +
                @insurance_expr = REYear.new(1, 7, 1, 7)
         
     | 
| 
      
 22 
     | 
    
         
            +
                @schedule.add(@insurance_payment, @insurance_expr)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @report = Report.new(@schedule)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              def test_initialize
         
     | 
| 
      
 26 
     | 
    
         
            +
                assert_equal @schedule, @report.schedule
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              def test_list
         
     | 
| 
      
 29 
     | 
    
         
            +
                range = PDate.day(2008, 1, 1)..PDate.day(2008,1,31)
         
     | 
| 
      
 30 
     | 
    
         
            +
                result = @report.list(range) 
         
     | 
| 
      
 31 
     | 
    
         
            +
                assert_equal(2, result.size)
         
     | 
| 
      
 32 
     | 
    
         
            +
                assert_equal(@gas_payment, result[PDate.day(2008, 1, 2)][0])
         
     | 
| 
      
 33 
     | 
    
         
            +
                assert_equal(@insurance_payment, result[PDate.day(2008, 1, 7)][0])
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            class PaymentTest < Test::Unit::TestCase
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def test_initialize
         
     | 
| 
      
 42 
     | 
    
         
            +
                p = Payment.new "Foo", 12
         
     | 
| 
      
 43 
     | 
    
         
            +
                assert_equal "Foo", p.id
         
     | 
| 
      
 44 
     | 
    
         
            +
                assert_equal 12, p.amount
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
    
        data/examples/reminder.rb
    CHANGED
    
    | 
         @@ -1,63 +1,63 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            # NOTE this is slightly broken; it is in the process of being fixed
         
     | 
| 
       4 
     | 
    
         
            -
            base = File.basename(Dir.pwd)
         
     | 
| 
       5 
     | 
    
         
            -
            if base == "examples" || base =~ /runt/
         
     | 
| 
       6 
     | 
    
         
            -
              Dir.chdir("..") if base == "examples"
         
     | 
| 
       7 
     | 
    
         
            -
              $LOAD_PATH.unshift(Dir.pwd + '/lib')
         
     | 
| 
       8 
     | 
    
         
            -
              Dir.chdir("examples") if base =~ /runt/
         
     | 
| 
       9 
     | 
    
         
            -
            end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
            require 'runt'
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            class Reminder
         
     | 
| 
       17 
     | 
    
         
            -
              include Runt
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
              def initialize(schedule)
         
     | 
| 
       20 
     | 
    
         
            -
                @schedule=schedule
         
     | 
| 
       21 
     | 
    
         
            -
              end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
              def next_times(event,end_point,now=Time.now)
         
     | 
| 
       24 
     | 
    
         
            -
                @schedule.dates(event,DateRange.new(now,end_point))
         
     | 
| 
       25 
     | 
    
         
            -
              end
         
     | 
| 
       26 
     | 
    
         
            -
            end 
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            # start of range whose occurrences we want to list
         
     | 
| 
       29 
     | 
    
         
            -
            # TODO fix Runt so this can be done with Time instead 
         
     | 
| 
       30 
     | 
    
         
            -
            #      e.g., now=Time.now
         
     | 
| 
       31 
     | 
    
         
            -
            #now=Time.parse("13:00")
         
     | 
| 
       32 
     | 
    
         
            -
            #now.date_precision=Runt::DPrecision::MIN
         
     | 
| 
       33 
     | 
    
         
            -
            now=Runt::PDate.min(2006,12,8,13,00)
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            # end of range
         
     | 
| 
       36 
     | 
    
         
            -
            soon=(now + 10.minutes)
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
            # Sanity check
         
     | 
| 
       39 
     | 
    
         
            -
            print "start: #{now.to_s} (#{now.date_precision}) end: #{soon.to_s} (#{soon.date_precision})\n"
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            #
         
     | 
| 
       42 
     | 
    
         
            -
            # Schedule used to house TemporalExpression describing the recurrence from 
         
     | 
| 
       43 
     | 
    
         
            -
            # which we'd list to generate a list of dates. In this example, some Event
         
     | 
| 
       44 
     | 
    
         
            -
            # occuring every 5 minutes.
         
     | 
| 
       45 
     | 
    
         
            -
            # 
         
     | 
| 
       46 
     | 
    
         
            -
            schedule=Runt::Schedule.new
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            # Some event whose schedule we're interested in
         
     | 
| 
       49 
     | 
    
         
            -
            event=Runt::Event.new("whatever")
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
            # Add the event to the schedule (
         
     | 
| 
       52 
     | 
    
         
            -
            # NOTE: any Object that is a sensible Hash key can be used
         
     | 
| 
       53 
     | 
    
         
            -
            schedule.add(event,Runt::EveryTE.new(now,5.minutes))
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            # Example domain Object using Runt 
         
     | 
| 
       56 
     | 
    
         
            -
            reminder=Reminder.new(schedule)
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            # Call our domain Object with the start and end times and the event
         
     | 
| 
       59 
     | 
    
         
            -
            # in which we're interested
         
     | 
| 
       60 
     | 
    
         
            -
            #puts "times (inclusive) = #{reminder.next_times(event,soon,now).join('\n')}"
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            puts "times (inclusive):"
         
     | 
| 
       63 
     | 
    
         
            -
            reminder.next_times(event,soon,now).each{|t| puts t}
         
     | 
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # NOTE this is slightly broken; it is in the process of being fixed
         
     | 
| 
      
 4 
     | 
    
         
            +
            base = File.basename(Dir.pwd)
         
     | 
| 
      
 5 
     | 
    
         
            +
            if base == "examples" || base =~ /runt/
         
     | 
| 
      
 6 
     | 
    
         
            +
              Dir.chdir("..") if base == "examples"
         
     | 
| 
      
 7 
     | 
    
         
            +
              $LOAD_PATH.unshift(Dir.pwd + '/lib')
         
     | 
| 
      
 8 
     | 
    
         
            +
              Dir.chdir("examples") if base =~ /runt/
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            require 'runt'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            class Reminder
         
     | 
| 
      
 17 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def initialize(schedule)
         
     | 
| 
      
 20 
     | 
    
         
            +
                @schedule=schedule
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def next_times(event,end_point,now=Time.now)
         
     | 
| 
      
 24 
     | 
    
         
            +
                @schedule.dates(event,DateRange.new(now,end_point))
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end 
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # start of range whose occurrences we want to list
         
     | 
| 
      
 29 
     | 
    
         
            +
            # TODO fix Runt so this can be done with Time instead 
         
     | 
| 
      
 30 
     | 
    
         
            +
            #      e.g., now=Time.now
         
     | 
| 
      
 31 
     | 
    
         
            +
            #now=Time.parse("13:00")
         
     | 
| 
      
 32 
     | 
    
         
            +
            #now.date_precision=Runt::DPrecision::MIN
         
     | 
| 
      
 33 
     | 
    
         
            +
            now=Runt::PDate.min(2006,12,8,13,00)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            # end of range
         
     | 
| 
      
 36 
     | 
    
         
            +
            soon=(now + 10.minutes)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            # Sanity check
         
     | 
| 
      
 39 
     | 
    
         
            +
            print "start: #{now.to_s} (#{now.date_precision}) end: #{soon.to_s} (#{soon.date_precision})\n"
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            #
         
     | 
| 
      
 42 
     | 
    
         
            +
            # Schedule used to house TemporalExpression describing the recurrence from 
         
     | 
| 
      
 43 
     | 
    
         
            +
            # which we'd list to generate a list of dates. In this example, some Event
         
     | 
| 
      
 44 
     | 
    
         
            +
            # occuring every 5 minutes.
         
     | 
| 
      
 45 
     | 
    
         
            +
            # 
         
     | 
| 
      
 46 
     | 
    
         
            +
            schedule=Runt::Schedule.new
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            # Some event whose schedule we're interested in
         
     | 
| 
      
 49 
     | 
    
         
            +
            event=Runt::Event.new("whatever")
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            # Add the event to the schedule (
         
     | 
| 
      
 52 
     | 
    
         
            +
            # NOTE: any Object that is a sensible Hash key can be used
         
     | 
| 
      
 53 
     | 
    
         
            +
            schedule.add(event,Runt::EveryTE.new(now,5.minutes))
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            # Example domain Object using Runt 
         
     | 
| 
      
 56 
     | 
    
         
            +
            reminder=Reminder.new(schedule)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            # Call our domain Object with the start and end times and the event
         
     | 
| 
      
 59 
     | 
    
         
            +
            # in which we're interested
         
     | 
| 
      
 60 
     | 
    
         
            +
            #puts "times (inclusive) = #{reminder.next_times(event,soon,now).join('\n')}"
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            puts "times (inclusive):"
         
     | 
| 
      
 63 
     | 
    
         
            +
            reminder.next_times(event,soon,now).each{|t| puts t}
         
     | 
    
        data/lib/runt.rb
    CHANGED
    
    | 
         @@ -1,219 +1,237 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #!/usr/bin/env ruby
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            # :title:Runt -- Ruby Temporal Expressions
         
     | 
| 
       4 
     | 
    
         
            -
            #
         
     | 
| 
       5 
     | 
    
         
            -
            # == Runt -- Ruby Temporal Expressions
         
     | 
| 
       6 
     | 
    
         
            -
            #
         
     | 
| 
       7 
     | 
    
         
            -
            # The usage and design patterns expressed in this library are mostly...*uhm*..
         
     | 
| 
       8 
     | 
    
         
            -
            # <em>entirely</em>..*cough*...based on a series of
         
     | 
| 
       9 
     | 
    
         
            -
            # <tt>articles</tt>[http://www.martinfowler.com] by Martin Fowler.
         
     | 
| 
       10 
     | 
    
         
            -
            #
         
     | 
| 
       11 
     | 
    
         
            -
            # It highly recommended that anyone using Runt (or writing
         
     | 
| 
       12 
     | 
    
         
            -
            # object-oriented software :) take a moment to peruse the wealth of useful info
         
     | 
| 
       13 
     | 
    
         
            -
            # that Fowler has made publicly available:
         
     | 
| 
       14 
     | 
    
         
            -
            #
         
     | 
| 
       15 
     | 
    
         
            -
            # * An excellent introductory summation of temporal <tt>patterns</tt>[http://martinfowler.com/ap2/timeNarrative.html]
         
     | 
| 
       16 
     | 
    
         
            -
            # * Recurring event <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
         
     | 
| 
       17 
     | 
    
         
            -
            #
         
     | 
| 
       18 
     | 
    
         
            -
            # Also, for those of you (like me, for example) still chained in your cubicle and forced
         
     | 
| 
       19 
     | 
    
         
            -
            # to write <tt>Java</tt>[http://java.sun.com] code, check out the original version of
         
     | 
| 
       20 
     | 
    
         
            -
            # project called <tt>ChronicJ</tt>[http://chronicj.org].
         
     | 
| 
       21 
     | 
    
         
            -
            #
         
     | 
| 
       22 
     | 
    
         
            -
            # ---
         
     | 
| 
       23 
     | 
    
         
            -
            # Author::    Matthew Lipper (mailto:mlipper@gmail.com)
         
     | 
| 
       24 
     | 
    
         
            -
            # Copyright:: Copyright (c) 2004 Digital Clash, LLC
         
     | 
| 
       25 
     | 
    
         
            -
            # License::   See LICENSE.txt
         
     | 
| 
       26 
     | 
    
         
            -
            #
         
     | 
| 
       27 
     | 
    
         
            -
            # = Warranty
         
     | 
| 
       28 
     | 
    
         
            -
            #
         
     | 
| 
       29 
     | 
    
         
            -
            # This software is provided "as is" and without any express or
         
     | 
| 
       30 
     | 
    
         
            -
            # implied warranties, including, without limitation, the implied
         
     | 
| 
       31 
     | 
    
         
            -
            # warranties of merchantibility and fitness for a particular
         
     | 
| 
       32 
     | 
    
         
            -
            # purpose.
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
            require 'time'
         
     | 
| 
       35 
     | 
    
         
            -
            require 'date'
         
     | 
| 
       36 
     | 
    
         
            -
            require 'date/format'
         
     | 
| 
       37 
     | 
    
         
            -
            require "runt/dprecision"
         
     | 
| 
       38 
     | 
    
         
            -
            require "runt/pdate"
         
     | 
| 
       39 
     | 
    
         
            -
            require "runt/temporalexpression"
         
     | 
| 
       40 
     | 
    
         
            -
            require "runt/schedule"
         
     | 
| 
       41 
     | 
    
         
            -
            require "runt/daterange"
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
            # 
     | 
| 
       46 
     | 
    
         
            -
            #  
     | 
| 
       47 
     | 
    
         
            -
            #  
     | 
| 
       48 
     | 
    
         
            -
            #
         
     | 
| 
       49 
     | 
    
         
            -
            # < 
     | 
| 
       50 
     | 
    
         
            -
            #
         
     | 
| 
       51 
     | 
    
         
            -
            module  
     | 
| 
       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 
     | 
    
         
            -
               
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
               
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
               
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
               
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
            #
         
     | 
| 
       159 
     | 
    
         
            -
            # 
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
              
         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
               
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
                 
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
             
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                 
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                 
     | 
| 
       193 
     | 
    
         
            -
                 
     | 
| 
       194 
     | 
    
         
            -
              end
         
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
               
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
              def  
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
               
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
             
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # :title:Runt -- Ruby Temporal Expressions
         
     | 
| 
      
 4 
     | 
    
         
            +
            #
         
     | 
| 
      
 5 
     | 
    
         
            +
            # == Runt -- Ruby Temporal Expressions
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # The usage and design patterns expressed in this library are mostly...*uhm*..
         
     | 
| 
      
 8 
     | 
    
         
            +
            # <em>entirely</em>..*cough*...based on a series of
         
     | 
| 
      
 9 
     | 
    
         
            +
            # <tt>articles</tt>[http://www.martinfowler.com] by Martin Fowler.
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            # It highly recommended that anyone using Runt (or writing
         
     | 
| 
      
 12 
     | 
    
         
            +
            # object-oriented software :) take a moment to peruse the wealth of useful info
         
     | 
| 
      
 13 
     | 
    
         
            +
            # that Fowler has made publicly available:
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # * An excellent introductory summation of temporal <tt>patterns</tt>[http://martinfowler.com/ap2/timeNarrative.html]
         
     | 
| 
      
 16 
     | 
    
         
            +
            # * Recurring event <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            # Also, for those of you (like me, for example) still chained in your cubicle and forced
         
     | 
| 
      
 19 
     | 
    
         
            +
            # to write <tt>Java</tt>[http://java.sun.com] code, check out the original version of
         
     | 
| 
      
 20 
     | 
    
         
            +
            # project called <tt>ChronicJ</tt>[http://chronicj.org].
         
     | 
| 
      
 21 
     | 
    
         
            +
            #
         
     | 
| 
      
 22 
     | 
    
         
            +
            # ---
         
     | 
| 
      
 23 
     | 
    
         
            +
            # Author::    Matthew Lipper (mailto:mlipper@gmail.com)
         
     | 
| 
      
 24 
     | 
    
         
            +
            # Copyright:: Copyright (c) 2004 Digital Clash, LLC
         
     | 
| 
      
 25 
     | 
    
         
            +
            # License::   See LICENSE.txt
         
     | 
| 
      
 26 
     | 
    
         
            +
            #
         
     | 
| 
      
 27 
     | 
    
         
            +
            # = Warranty
         
     | 
| 
      
 28 
     | 
    
         
            +
            #
         
     | 
| 
      
 29 
     | 
    
         
            +
            # This software is provided "as is" and without any express or
         
     | 
| 
      
 30 
     | 
    
         
            +
            # implied warranties, including, without limitation, the implied
         
     | 
| 
      
 31 
     | 
    
         
            +
            # warranties of merchantibility and fitness for a particular
         
     | 
| 
      
 32 
     | 
    
         
            +
            # purpose.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            require 'time'
         
     | 
| 
      
 35 
     | 
    
         
            +
            require 'date'
         
     | 
| 
      
 36 
     | 
    
         
            +
            require 'date/format'
         
     | 
| 
      
 37 
     | 
    
         
            +
            require "runt/dprecision"
         
     | 
| 
      
 38 
     | 
    
         
            +
            require "runt/pdate"
         
     | 
| 
      
 39 
     | 
    
         
            +
            require "runt/temporalexpression"
         
     | 
| 
      
 40 
     | 
    
         
            +
            require "runt/schedule"
         
     | 
| 
      
 41 
     | 
    
         
            +
            require "runt/daterange"
         
     | 
| 
      
 42 
     | 
    
         
            +
            require "runt/sugar"
         
     | 
| 
      
 43 
     | 
    
         
            +
            require "runt/expressionbuilder"
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            #
         
     | 
| 
      
 46 
     | 
    
         
            +
            # The Runt module is the main namespace for all Runt modules and classes. Using
         
     | 
| 
      
 47 
     | 
    
         
            +
            # require statements, it makes the entire Runt library available.It also
         
     | 
| 
      
 48 
     | 
    
         
            +
            # defines some new constants and exposes some already defined in the standard
         
     | 
| 
      
 49 
     | 
    
         
            +
            # library classes <tt>Date</tt> and <tt>DateTime</tt>.
         
     | 
| 
      
 50 
     | 
    
         
            +
            #
         
     | 
| 
      
 51 
     | 
    
         
            +
            # <b>See also</b> runt/sugar_rb which re-opens this module and adds 
         
     | 
| 
      
 52 
     | 
    
         
            +
            # some additional functionality
         
     | 
| 
      
 53 
     | 
    
         
            +
            #
         
     | 
| 
      
 54 
     | 
    
         
            +
            # <b>See also</b> date.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
            #
         
     | 
| 
      
 56 
     | 
    
         
            +
            module Runt
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 59 
     | 
    
         
            +
                
         
     | 
| 
      
 60 
     | 
    
         
            +
                def day_name(number)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  Date::DAYNAMES[number]
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
                
         
     | 
| 
      
 64 
     | 
    
         
            +
                def month_name(number)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  Date::MONTHNAMES[number]
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def format_time(date)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  date.strftime('%I:%M%p')
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def format_date(date)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  date.ctime
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
                
         
     | 
| 
      
 76 
     | 
    
         
            +
                #
         
     | 
| 
      
 77 
     | 
    
         
            +
                # Cut and pasted from activesupport-1.2.5/lib/inflector.rb
         
     | 
| 
      
 78 
     | 
    
         
            +
                #
         
     | 
| 
      
 79 
     | 
    
         
            +
                def ordinalize(number)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  if (number.to_i==-1)
         
     | 
| 
      
 81 
     | 
    
         
            +
            	'last'
         
     | 
| 
      
 82 
     | 
    
         
            +
                  elsif (number.to_i==-2)
         
     | 
| 
      
 83 
     | 
    
         
            +
            	'second to last'  
         
     | 
| 
      
 84 
     | 
    
         
            +
                  elsif (11..13).include?(number.to_i % 100)
         
     | 
| 
      
 85 
     | 
    
         
            +
            	"#{number}th"
         
     | 
| 
      
 86 
     | 
    
         
            +
                  else
         
     | 
| 
      
 87 
     | 
    
         
            +
            	case number.to_i % 10
         
     | 
| 
      
 88 
     | 
    
         
            +
            	  when 1: "#{number}st"
         
     | 
| 
      
 89 
     | 
    
         
            +
            	  when 2: "#{number}nd"
         
     | 
| 
      
 90 
     | 
    
         
            +
            	  when 3: "#{number}rd"
         
     | 
| 
      
 91 
     | 
    
         
            +
            	  else    "#{number}th"
         
     | 
| 
      
 92 
     | 
    
         
            +
            	end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              #Yes it's true, I'm a big idiot!
         
     | 
| 
      
 99 
     | 
    
         
            +
              Sunday = Date::DAYNAMES.index("Sunday")
         
     | 
| 
      
 100 
     | 
    
         
            +
              Monday = Date::DAYNAMES.index("Monday")
         
     | 
| 
      
 101 
     | 
    
         
            +
              Tuesday = Date::DAYNAMES.index("Tuesday")
         
     | 
| 
      
 102 
     | 
    
         
            +
              Wednesday = Date::DAYNAMES.index("Wednesday")
         
     | 
| 
      
 103 
     | 
    
         
            +
              Thursday = Date::DAYNAMES.index("Thursday")
         
     | 
| 
      
 104 
     | 
    
         
            +
              Friday = Date::DAYNAMES.index("Friday")
         
     | 
| 
      
 105 
     | 
    
         
            +
              Saturday = Date::DAYNAMES.index("Saturday")
         
     | 
| 
      
 106 
     | 
    
         
            +
              Sun = Date::ABBR_DAYNAMES.index("Sun")
         
     | 
| 
      
 107 
     | 
    
         
            +
              Mon = Date::ABBR_DAYNAMES.index("Mon")
         
     | 
| 
      
 108 
     | 
    
         
            +
              Tue = Date::ABBR_DAYNAMES.index("Tue")
         
     | 
| 
      
 109 
     | 
    
         
            +
              Wed = Date::ABBR_DAYNAMES.index("Wed")
         
     | 
| 
      
 110 
     | 
    
         
            +
              Thu = Date::ABBR_DAYNAMES.index("Thu")
         
     | 
| 
      
 111 
     | 
    
         
            +
              Fri = Date::ABBR_DAYNAMES.index("Fri")
         
     | 
| 
      
 112 
     | 
    
         
            +
              Sat = Date::ABBR_DAYNAMES.index("Sat")
         
     | 
| 
      
 113 
     | 
    
         
            +
              January = Date::MONTHNAMES.index("January")
         
     | 
| 
      
 114 
     | 
    
         
            +
              February = Date::MONTHNAMES.index("February")
         
     | 
| 
      
 115 
     | 
    
         
            +
              March = Date::MONTHNAMES.index("March")
         
     | 
| 
      
 116 
     | 
    
         
            +
              April = Date::MONTHNAMES.index("April")
         
     | 
| 
      
 117 
     | 
    
         
            +
              May = Date::MONTHNAMES.index("May")
         
     | 
| 
      
 118 
     | 
    
         
            +
              June = Date::MONTHNAMES.index("June")
         
     | 
| 
      
 119 
     | 
    
         
            +
              July = Date::MONTHNAMES.index("July")
         
     | 
| 
      
 120 
     | 
    
         
            +
              August = Date::MONTHNAMES.index("August")
         
     | 
| 
      
 121 
     | 
    
         
            +
              September = Date::MONTHNAMES.index("September")
         
     | 
| 
      
 122 
     | 
    
         
            +
              October = Date::MONTHNAMES.index("October")
         
     | 
| 
      
 123 
     | 
    
         
            +
              November = Date::MONTHNAMES.index("November")
         
     | 
| 
      
 124 
     | 
    
         
            +
              December = Date::MONTHNAMES.index("December")
         
     | 
| 
      
 125 
     | 
    
         
            +
              First = 1
         
     | 
| 
      
 126 
     | 
    
         
            +
              Second = 2
         
     | 
| 
      
 127 
     | 
    
         
            +
              Third = 3
         
     | 
| 
      
 128 
     | 
    
         
            +
              Fourth = 4
         
     | 
| 
      
 129 
     | 
    
         
            +
              Fifth = 5
         
     | 
| 
      
 130 
     | 
    
         
            +
              Sixth = 6
         
     | 
| 
      
 131 
     | 
    
         
            +
              Seventh = 7
         
     | 
| 
      
 132 
     | 
    
         
            +
              Eighth = 8
         
     | 
| 
      
 133 
     | 
    
         
            +
              Eigth = 8  # Will be removed in v0.9.0
         
     | 
| 
      
 134 
     | 
    
         
            +
              Ninth = 9
         
     | 
| 
      
 135 
     | 
    
         
            +
              Tenth = 10
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
              private
         
     | 
| 
      
 138 
     | 
    
         
            +
              class ApplyLast #:nodoc:
         
     | 
| 
      
 139 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 140 
     | 
    
         
            +
                  @negate=Proc.new{|n| n*-1}
         
     | 
| 
      
 141 
     | 
    
         
            +
                end
         
     | 
| 
      
 142 
     | 
    
         
            +
                def [](arg)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  @negate.call(arg)
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
              end
         
     | 
| 
      
 146 
     | 
    
         
            +
              LastProc = ApplyLast.new
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
              public
         
     | 
| 
      
 149 
     | 
    
         
            +
              Last = LastProc[First]
         
     | 
| 
      
 150 
     | 
    
         
            +
              Last_of = LastProc[First]
         
     | 
| 
      
 151 
     | 
    
         
            +
              Second_to_last = LastProc[Second]
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            #
         
     | 
| 
      
 156 
     | 
    
         
            +
            # Add precision +Runt::DPrecision+ to standard library classes Date and DateTime 
         
     | 
| 
      
 157 
     | 
    
         
            +
            # (which is a subclass of Date). Also, add an inlcude? method for interoperability
         
     | 
| 
      
 158 
     | 
    
         
            +
            # with +Runt::TExpr+ classes
         
     | 
| 
      
 159 
     | 
    
         
            +
            #
         
     | 
| 
      
 160 
     | 
    
         
            +
            class Date
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              attr_accessor :date_precision
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
              def include?(expr)
         
     | 
| 
      
 167 
     | 
    
         
            +
                eql?(expr)
         
     | 
| 
      
 168 
     | 
    
         
            +
              end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
              def date_precision
         
     | 
| 
      
 171 
     | 
    
         
            +
                return @date_precision unless @date_precision.nil? 
         
     | 
| 
      
 172 
     | 
    
         
            +
                return Runt::DPrecision::DEFAULT 
         
     | 
| 
      
 173 
     | 
    
         
            +
              end 	  
         
     | 
| 
      
 174 
     | 
    
         
            +
            end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            #
         
     | 
| 
      
 177 
     | 
    
         
            +
            # Add the ability to use Time class 
         
     | 
| 
      
 178 
     | 
    
         
            +
            #
         
     | 
| 
      
 179 
     | 
    
         
            +
            # Contributed by Paul Wright
         
     | 
| 
      
 180 
     | 
    
         
            +
            #
         
     | 
| 
      
 181 
     | 
    
         
            +
            class Time
         
     | 
| 
      
 182 
     | 
    
         
            +
              
         
     | 
| 
      
 183 
     | 
    
         
            +
              include Runt
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
              attr_accessor :date_precision
         
     | 
| 
      
 186 
     | 
    
         
            +
              alias_method :old_initialize, :initialize
         
     | 
| 
      
 187 
     | 
    
         
            +
              def initialize(*args)
         
     | 
| 
      
 188 
     | 
    
         
            +
                if(args[0].instance_of?(Runt::DPrecision::Precision))
         
     | 
| 
      
 189 
     | 
    
         
            +
                  @precision=args.shift
         
     | 
| 
      
 190 
     | 
    
         
            +
                else
         
     | 
| 
      
 191 
     | 
    
         
            +
                  @precision=Runt::DPrecision::DEFAULT
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
                old_initialize(*args)
         
     | 
| 
      
 194 
     | 
    
         
            +
              end
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 197 
     | 
    
         
            +
                alias_method :old_parse, :parse
         
     | 
| 
      
 198 
     | 
    
         
            +
                def parse(*args)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  precision=Runt::DPrecision::DEFAULT
         
     | 
| 
      
 200 
     | 
    
         
            +
                  if(args[0].instance_of?(Runt::DPrecision::Precision))
         
     | 
| 
      
 201 
     | 
    
         
            +
                    precision=args.shift
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
                  _parse=old_parse(*args)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  _parse.date_precision=precision
         
     | 
| 
      
 205 
     | 
    
         
            +
                  _parse
         
     | 
| 
      
 206 
     | 
    
         
            +
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
              end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
              def date_precision
         
     | 
| 
      
 210 
     | 
    
         
            +
                return @date_precision unless @date_precision.nil?
         
     | 
| 
      
 211 
     | 
    
         
            +
                return Runt::DPrecision::DEFAULT
         
     | 
| 
      
 212 
     | 
    
         
            +
              end
         
     | 
| 
      
 213 
     | 
    
         
            +
            end
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
            #
         
     | 
| 
      
 216 
     | 
    
         
            +
            # Useful shortcuts!
         
     | 
| 
      
 217 
     | 
    
         
            +
            #
         
     | 
| 
      
 218 
     | 
    
         
            +
            # Contributed by Ara T. Howard who is pretty sure he got the idea from 
         
     | 
| 
      
 219 
     | 
    
         
            +
            # somewhere else. :-)
         
     | 
| 
      
 220 
     | 
    
         
            +
            #
         
     | 
| 
      
 221 
     | 
    
         
            +
            class Numeric #:nodoc:
         
     | 
| 
      
 222 
     | 
    
         
            +
              def microseconds() Float(self  * (10 ** -6)) end
         
     | 
| 
      
 223 
     | 
    
         
            +
              def milliseconds() Float(self  * (10 ** -3)) end
         
     | 
| 
      
 224 
     | 
    
         
            +
              def seconds() self end
         
     | 
| 
      
 225 
     | 
    
         
            +
              def minutes() 60 * seconds end
         
     | 
| 
      
 226 
     | 
    
         
            +
              def hours() 60 * minutes end
         
     | 
| 
      
 227 
     | 
    
         
            +
              def days() 24 * hours end
         
     | 
| 
      
 228 
     | 
    
         
            +
              def weeks() 7 * days end
         
     | 
| 
      
 229 
     | 
    
         
            +
              def months() 30 * days end
         
     | 
| 
      
 230 
     | 
    
         
            +
              def years() 365 * days end
         
     | 
| 
      
 231 
     | 
    
         
            +
              def decades() 10 * years end
         
     | 
| 
      
 232 
     | 
    
         
            +
              # This causes RDoc to hurl:  
         
     | 
| 
      
 233 
     | 
    
         
            +
              %w[
         
     | 
| 
      
 234 
     | 
    
         
            +
              microseconds milliseconds seconds minutes hours days weeks months years decades
         
     | 
| 
      
 235 
     | 
    
         
            +
              ].each{|m| alias_method m.chop, m}
         
     | 
| 
      
 236 
     | 
    
         
            +
            end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     |