Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

=== 0.6.0 - 5 June 2009

 Time for a minor version bump.
 * Improved overall enumeration performance bypassing most of the effects of the poor performance of Ruby's DateTime class.
 * Added a framework for performance monitoring during development.
   - New performance directory with subdirs for code to be monitored for performance (subjects)
   - New script files:
        script/benchmark_subject runs a ruby benchmark on one performance subject
        script/profile_subject runs ruby-prof for a subject and puts a kcachegrind compatible calltree in the performance_data directory.
   - New rake tasks:
        performance:benchmark runs benchmarks against all subjects in the performance directory and produces a consolidated output file in performance_data/benchmarks.out
        performance:profile runs script/profile_subject against all subjects in the performance directory.
  • Loading branch information...
commit b02493be6f1b273a55876fcbb8d210ec761474c4 1 parent 9724c17
@rubyredrick authored
Showing with 409,356 additions and 414,298 deletions.
  1. +11 −0 History.txt
  2. +9 −4 Manifest.txt
  3. +1 −4 README.txt
  4. +1 −1  lib/ri_cal.rb
  5. +0 −1  lib/ri_cal/component/calendar.rb
  6. +1 −11 lib/ri_cal/core_extensions/string/conversions.rb
  7. +0 −17 lib/ri_cal/core_extensions/time/conversions.rb
  8. +0 −33 lib/ri_cal/core_extensions/time/week_day_predicates.rb
  9. +214 −0 lib/ri_cal/fast_date_time.rb
  10. +3 −3 lib/ri_cal/occurrence_enumerator.rb
  11. +19 −25 lib/ri_cal/property_value/date.rb
  12. +25 −10 lib/ri_cal/property_value/date_time.rb
  13. +8 −30 lib/ri_cal/property_value/date_time/time_machine.rb
  14. +1 −1  lib/ri_cal/property_value/date_time/timezone_support.rb
  15. +1 −1  performance/paris_eastern/subject.rb
  16. +1 −1  performance/utah_cycling/subject.rb
  17. +12 −12 performance_data/benchmarks.out
  18. +79,700 −125,488 performance_data/paris_eastern.calltree
  19. +37,742 −53,898 performance_data/penultimate_weekday.calltree
  20. +173,988 −232,520 performance_data/psm_big_enum.calltree
  21. +117,203 −1,890 performance_data/utah_cycling.calltree
  22. +3 −3 ri_cal.gemspec
  23. +2 −1  spec/ri_cal/component/event_spec.rb
  24. +1 −1  spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb
  25. +67 −0 spec/ri_cal/fast_date_time_spec.rb
  26. +343 −343 spec/ri_cal/occurrence_enumerator_spec.rb
View
11 History.txt
@@ -1,3 +1,14 @@
+=== 0.6.0 - 5 June 2009
+ Time for a minor version bump.
+ * Improved overall enumeration performance bypassing most of the effects of the poor performance of Ruby's DateTime class.
+ * Added a framework for performance monitoring during development.
+ - New performance directory with subdirs for code to be monitored for performance (subjects)
+ - New script files:
+ script/benchmark_subject runs a ruby benchmark on one performance subject
+ script/profile_subject runs ruby-prof for a subject and puts a kcachegrind compatible calltree in the performance_data directory.
+ - New rake tasks:
+ performance:benchmark runs benchmarks against all subjects in the performance directory and produces a consolidated output file in performance_data/benchmarks.out
+ performance:profile runs script/profile_subject against all subjects in the performance directory.
=== 0.5.3 - 1 June, 2009
* Improved performance of time zone enumeration, TimeZonePeriod now caches occurrences
* Added a profiling directory which contains ruby programs which benchmark and/or profile performance
View
13 Manifest.txt
@@ -46,6 +46,7 @@ lib/ri_cal/core_extensions/time/calculations.rb
lib/ri_cal/core_extensions/time/conversions.rb
lib/ri_cal/core_extensions/time/tzid_access.rb
lib/ri_cal/core_extensions/time/week_day_predicates.rb
+lib/ri_cal/fast_date_time.rb
lib/ri_cal/floating_timezone.rb
lib/ri_cal/invalid_property_value.rb
lib/ri_cal/invalid_timezone_identifer.rb
@@ -89,15 +90,18 @@ lib/ri_cal/property_value/text.rb
lib/ri_cal/property_value/uri.rb
lib/ri_cal/property_value/utc_offset.rb
lib/ri_cal/required_timezones.rb
-profiling/ical_files/profile3.ics
-profiling/profile1.rb
-profiling/profile2.rb
-profiling/profile3.rb
+performance/paris_eastern/subject.rb
+performance/penultimate_weekday/subject.rb
+performance/psm_big_enum/ical.ics
+performance/psm_big_enum/subject.rb
+performance/utah_cycling/subject.rb
ri_cal.gemspec
sample_ical_files/from_ical_dot_app/test1.ics
+script/benchmark_subject
script/console
script/destroy
script/generate
+script/profile_subject
script/txt2html
spec/ri_cal/component/alarm_spec.rb
spec/ri_cal/component/calendar_spec.rb
@@ -111,6 +115,7 @@ spec/ri_cal/component_spec.rb
spec/ri_cal/core_extensions/string/conversions_spec.rb
spec/ri_cal/core_extensions/time/calculations_spec.rb
spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb
+spec/ri_cal/fast_date_time_spec.rb
spec/ri_cal/occurrence_enumerator_spec.rb
spec/ri_cal/parser_spec.rb
spec/ri_cal/property_value/date_spec.rb
View
5 README.txt
@@ -348,12 +348,9 @@ or by a recent(>= 2.2) version of the ActiveSupport gem which is part of Ruby on
=== From github
- #TODO: publish to github
-
==== As a Gem
- #TODO: add the gem source info for github
- sudo gem install ????? --source http://github.com/????
+ sudo gem install rubyredrick-ri_cal --source http://gems.github.com/
==== From source
View
2  lib/ri_cal.rb
@@ -14,7 +14,7 @@ module RiCal
autoload :OccurrenceEnumerator, "#{my_dir}/ri_cal/occurrence_enumerator.rb"
# :stopdoc:
- VERSION = '0.5.3'
+ VERSION = '0.6.0'
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
View
1  lib/ri_cal/component/calendar.rb
@@ -140,7 +140,6 @@ def utc_to_local(local) #:nodoc:
def rational_utc_offset(local)
- # 86400 is the number of seconds in a day
RiCal.RationalOffset[tzinfo.period_for_local(local, true).utc_total_offset]
end
View
12 lib/ri_cal/core_extensions/string/conversions.rb
@@ -47,17 +47,7 @@ def to_ri_cal_occurrence_list_value(timezone_finder = nil)
raise "Invalid value for occurrence list #{self.inspect}"
end
end
-
- # code stolen from ActiveSupport Gem
- unless ::String.instance_methods.include?("camelize")
- # Convert the receiver to camelized form
- # This method duplicates the method provided by ActiveSupport, and will only be defined
- # by the RiCal gem if it is not already defined.
- def camelize
- self.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
- end
- end
- end
+ end
end
end
end
View
17 lib/ri_cal/core_extensions/time/conversions.rb
@@ -27,23 +27,6 @@ def with_floating_timezone
end
unless defined? ActiveSupport
- # Converts a Time object to a Date, dropping hour, minute, and second precision.
- #
- # my_time = Time.now # => Mon Nov 12 22:59:51 -0500 2007
- # my_time.to_date # => Mon, 12 Nov 2007
- #
- # your_time = Time.parse("1/13/2009 1:13:03 P.M.") # => Tue Jan 13 13:13:03 -0500 2009
- # your_time.to_date # => Tue, 13 Jan 2009
- def to_date
- ::Date.new(year, month, day)
- end
-
- # A method to keep Time, Date and DateTime instances interchangeable on conversions.
- # In this case, it simply returns +self+.
- def to_time
- self
- end
-
# Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.
#
# my_time = Time.now # => Mon Nov 12 23:04:21 -0500 2007
View
33 lib/ri_cal/core_extensions/time/week_day_predicates.rb
@@ -8,39 +8,6 @@ module Time #:nodoc:
# This module is included by Time, Date, and DateTime
module WeekDayPredicates
- # Determine the equivalent time on the day which falls on a particular weekday of the same year as the receiver
- #
- # == Parameters
- # n:: the ordinal number being requested
- # which_wday:: the weekday using Ruby time conventions, i.e. 0 => Sunday, 1 => Monday, ...
-
- # e.g. to obtain the 2nd Monday of the receivers year use
- #
- # time.nth_wday_in_year(2, 1)
- def nth_wday_in_year(n, which_wday, for_time = self)
- if n > 0
- first_of_year = for_time.to_ri_cal_property_value.change(:month => 1, :day => 1)
- first_in_year = first_of_year.advance(:days => (which_wday - first_of_year.wday + 7) % 7)
- first_in_year.advance(:days => (7*(n - 1)))
- else
- december25 = for_time.to_ri_cal_property_value.change(:month => 12, :day => 25)
- last_in_year = december25.advance(:days => (which_wday - december25.wday + 7) % 7)
- last_in_year.advance(:days => (7 * (n + 1)))
- end
- end
-
- # A predicate to determine whether or not the receiver falls on a particular weekday of its year.
- #
- # See #nth_wday_in_year
- #
- # == Parameters
- # n:: the ordinal number being requested
- # which_wday:: the weekday using Ruby time conventions, i.e. 0 => Sunday, 1 => Monday, ...
- def nth_wday_in_year?(n, which_wday)
- target = nth_wday_in_year(n, which_wday)
- [self.year, self.mon, self.day] == [target.year, target.mon, target.day]
- end
-
# Determine the day which falls on a particular weekday of the same month as the receiver
#
# == Parameters
View
214 lib/ri_cal/fast_date_time.rb
@@ -0,0 +1,214 @@
+module RiCal
+ #- ©2009 Rick DeNatale
+ #- All rights reserved. Refer to the file README.txt for the license
+ #
+ # FastDateTime mimics the Ruby Standard library DateTime class but avoids the use of Rational
+ # Instead of using a Rational for the utc offset, FastDateTime uses an integer seconds value
+ class FastDateTime
+ attr_accessor :date, :hour, :min, :sec, :offset, :secs_since_bod
+
+ SECONDS_IN_A_DAY = 60*60*24 unless defined? SECONDS_IN_A_DAY
+
+ include Comparable
+
+ def initialize(year, month, day, hour, min, sec, offset_seconds)
+ @date = Date.civil(year, month, day)
+ @secs_since_bod = hms_to_seconds(hour, min, sec)
+ @hour, @min, @sec, @offset = hour, min, sec, offset_seconds
+ end
+
+ def self.from_date_time(date_time)
+ new(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.min, date_time.sec, (date_time.offset * SECONDS_IN_A_DAY).to_i)
+ end
+
+ alias_method :utc_offset_seconds, :offset
+
+ def ical_str
+ "%04d%02d%02dT%02d%02d%02d" % [year, month, day, hour, min, sec]
+ end
+
+ def ical_date_str
+ "%04d%02d%02d" % [year, month, day]
+ end
+
+ def year
+ @date.year
+ end
+
+ def month
+ @date.month
+ end
+
+ alias_method :mon, :month
+
+ def day
+ @date.day
+ end
+
+ def wday
+ @date.wday
+ end
+
+ def to_datetime
+ DateTime.civil(year, month, day, hour, min, sec, RiCal.RationalOffset[utc_offset_seconds])
+ end
+
+ def ==(other)
+ [date, secs_since_bod, offset] == [other.date, other.secs_since_bod, other.offset]
+ end
+
+ def <=> (other)
+ if FastDateTime === other
+ [date, secs_since_bod] <=> [other.date, other.secs_since_bod]
+ else
+ [year, month, day, hour, min, sec] <=> [other.year, other.month, other.day, other.hour, other.min, other.sec]
+ end
+ end
+
+ def to_s
+ "#{year}/#{month}/#{day} #{hour}:#{min}:#{sec} #{offset}"
+ end
+
+ # def jd
+ # date.jd
+ # end
+ #
+ def days_in_month
+ date.days_in_month
+ end
+
+ alias_method :inspect, :to_s
+
+ # Return a new FastDateTime based on the receiver but with changes specified by the options
+ def change(options)
+ FastDateTime.new(
+ options[:year] || year,
+ options[:month] || month,
+ options[:day] || day,
+ options[:hour] || hour,
+ options[:min] || (options[:hour] ? 0 : min),
+ options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec),
+ options[:offset] || offset
+ )
+ end
+
+ # def new_offset(ofst)
+ # if ofst == offset
+ # self
+ # else
+ # advance(:seconds => offset - ofset, :offset => ofst)
+ # end
+ # end
+
+ def hms_to_seconds(hours, minutes, seconds)
+ seconds + 60 *(minutes + (60 * hours))
+ end
+
+ def seconds_to_hms(total_seconds)
+ sign = total_seconds <=> 0
+ remaining = total_seconds.abs
+ seconds = sign * (remaining % 60)
+ remaining = remaining / 60
+ minutes = sign * (remaining % 60)
+ [remaining / 60, minutes, seconds]
+ end
+
+ def adjust_day_delta(day_delta, new_secs_since_bod)
+ if new_secs_since_bod == 0
+ [day_delta, new_secs_since_bod]
+ elsif new_secs_since_bod > 0
+ [day_delta + (new_secs_since_bod / SECONDS_IN_A_DAY), new_secs_since_bod % SECONDS_IN_A_DAY]
+ else new_secs_since_bod
+ [day_delta - (1 + new_secs_since_bod.abs / SECONDS_IN_A_DAY),
+ SECONDS_IN_A_DAY - (new_secs_since_bod.abs % SECONDS_IN_A_DAY)]
+ end
+ end
+
+
+ def advance(options) # :nodoc:
+ new_date = @date
+ new_offset = options[:offset] || offset
+ month_delta = (options[:years] || 0) * 12 + (options[:months] || 0)
+ day_delta = (options[:weeks] || 0) * 7 + (options[:days] || 0)
+ sec_delta = hms_to_seconds((options[:hours] || 0), (options[:minutes] || 0), (options[:seconds] || 0))
+ day_delta, new_secs_since_bod = *adjust_day_delta(day_delta, secs_since_bod + sec_delta)
+ new_hour, new_min, new_sec = *seconds_to_hms(new_secs_since_bod)
+ new_date = new_date >> month_delta unless month_delta == 0
+ new_date += day_delta unless day_delta == 0
+ FastDateTime.new(new_date.year, new_date.month, new_date.day, new_hour, new_min, new_sec, new_offset)
+ end
+
+ # Determine the day which falls on a particular weekday of the same month as the receiver
+ #
+ # == Parameters
+ # n:: the ordinal number being requested
+ # which_wday:: the weekday using Ruby time conventions, i.e. 0 => Sunday, 1 => Monday, ...
+
+ # e.g. to obtain the 3nd Tuesday of the receivers month use
+ #
+ # time.nth_wday_in_month(2, 2)
+ def nth_wday_in_month(n, which_wday)
+ first_of_month = change(:day => 1)
+ first_in_month = first_of_month.advance(:days => (which_wday - first_of_month.wday))
+ first_in_month = first_in_month.advance(:days => 7) if first_in_month.month != first_of_month.month
+ if n > 0
+ first_in_month.advance(:days => (7*(n - 1)))
+ else
+ possible = first_in_month.advance(:days => 21)
+ possible = possible.advance(:days => 7) while possible.month == first_in_month.month
+ last_in_month = possible.advance(:days => - 7)
+ (last_in_month.advance(:days => - (7*(n.abs - 1))))
+ end
+ end
+
+ # Determine the equivalent time on the day which falls on a particular weekday of the same year as the receiver
+ #
+ # == Parameters
+ # n:: the ordinal number being requested
+ # which_wday:: the weekday using Ruby time conventions, i.e. 0 => Sunday, 1 => Monday, ...
+
+ # e.g. to obtain the 2nd Monday of the receivers year use
+ #
+ # time.nth_wday_in_year(2, 1)
+ def nth_wday_in_year(n, which_wday)
+ if n > 0
+ first_of_year = change(:month => 1, :day => 1)
+ first_in_year = first_of_year.advance(:days => (which_wday - first_of_year.wday + 7) % 7)
+ first_in_year.advance(:days => (7*(n - 1)))
+ else
+ december25 = change(:month => 12, :day => 25)
+ last_in_year = december25.advance(:days => (which_wday - december25.wday + 7) % 7)
+ last_in_year.advance(:days => (7 * (n + 1)))
+ end
+ end
+
+
+ # Return a DateTime which is the beginning of the first day on or before the receiver
+ # with the specified wday
+ def start_of_week_with_wkst(wkst)
+ wkst ||= 1
+ date = @date
+ date -= 1 while date.wday != wkst
+ date
+ end
+
+ def iso_weeks_in_year(wkst)
+ @date.iso_weeks_in_year(wkst)
+ end
+
+ def iso_year_start(wkst)
+ @date.iso_year_start(wkst)
+ end
+
+ def iso_year_and_week_one_start(wkst)
+ @date.iso_year_and_week_one_start(wkst)
+ end
+
+ def cmp_fast_date_time_value(other)
+ other <=> self
+ end
+
+
+ end
+
+end
View
6 lib/ri_cal/occurrence_enumerator.rb
@@ -222,10 +222,10 @@ def set_occurrence_properties!(occurrence) # :nodoc:
@exdate_property = nil
@recurrence_id_property = occurrence_start
if @dtend_property && !occurrence_end
- occurrence_end = occurrence_start + (@dtend_property - @dtstart_property)
+ occurrence_end = occurrence_start + (@dtend_property - @dtstart_property)
end
- @dtstart_property = dtstart_property.for_occurrence(occurrence_start)
- @dtend_property = dtend_property.for_occurrence(occurrence_end) if @dtend_property
+ @dtstart_property = @dtstart_property.for_occurrence(occurrence_start)
+ @dtend_property = (@dtend_property || @dtstart_property).for_occurrence(occurrence_end) if occurrence_end
self
end
View
44 lib/ri_cal/property_value/date.rb
@@ -15,7 +15,7 @@ def self.valid_string?(string) #:nodoc:
# Returns the value of the reciever as an RFC 2445 iCalendar string
def value
if @date_time_value
- @date_time_value.strftime("%Y%m%d")
+ @date_time_value.ical_date_str
else
nil
end
@@ -34,9 +34,11 @@ def value=(val)
when nil
@date_time_value = nil
when String
- @date_time_value = ::DateTime.parse(::DateTime.parse(val).strftime("%Y%m%d"))
+ @date_time_value = FastDateTime.from_date_time(::DateTime.parse(::DateTime.parse(val).strftime("%Y%m%d")))
when ::Time, ::Date, ::DateTime
- @date_time_value = ::DateTime.parse(val.strftime("%Y%m%d"))
+ @date_time_value = FastDateTime.from_date_time(::DateTime.parse(val.strftime("%Y%m%d")))
+ when FastDateTime
+ @date_time_value = val
end
end
@@ -69,7 +71,7 @@ def day
# Returns the ruby representation a ::Date
def ruby_value
- ::Date.parse(@date_time_value.strftime("%Y%m%d"))
+ @date_time_value.date
end
alias_method :to_ri_cal_ruby_value, :ruby_value
@@ -89,24 +91,12 @@ def to_ri_cal_date_or_date_time_value
self
end
- def compute_change(d, options) #:nodoc:
- ::Date.civil((options[:year] || d.year), (options[:month] || d.month), (options[:day] || d.day))
- end
-
- def compute_advance(d, options) #:nodoc:
- d = d >> options[:years] * 12 if options[:years]
- d = d >> options[:months] if options[:months]
- d = d + options[:weeks] * 7 if options[:weeks]
- d = d + options[:days] if options[:days]
- compute_change(@date_time_value, :year => d.year, :month => d.month, :day => d.day)
- end
-
def advance(options) #:nodoc:
- PropertyValue::Date.new(timezone_finder, :value => compute_advance(@date_time_value, options), :params =>(params ? params.dup : nil) )
+ PropertyValue::Date.new(timezone_finder, :value => @date_time_value.advance(options), :params =>(params ? params.dup : nil) )
end
def change(options) #:nodoc:
- PropertyValue::Date.new(timezone_finder,:value => compute_change(@date_time_value, options), :params => (params ? params.dup : nil) )
+ PropertyValue::Date.new(timezone_finder,:value => @date_time_value.change(options), :params => (params ? params.dup : nil) )
end
def add_date_times_to(required_timezones) #:nodoc:
@@ -146,26 +136,30 @@ def occurrence_period(default_duration) #:nodoc:
date_time = self.to_ri_cal_date_time_value
RiCal::OccurrencePeriod.new(date_time, date_time.advance(:hours => 24, :seconds => -1))
end
-
+
def start_of_day?
true
end
-
+
+ def to_floating_date_time_property
+ PropertyValue::DateTime.new(timezone_finder, :value => @date_time_value.ical_str)
+ end
+
def to_zulu_occurrence_range_start_time
- to_ri_cal_date_time_value.to_zulu_occurrence_range_start_time
+ to_floating_date_time_property.to_zulu_occurrence_range_start_time
end
-
+
def to_zulu_occurrence_range_finish_time
to_ri_cal_date_time_value.end_of_day.to_zulu_occurrence_range_finish_time
end
-
+
def to_finish_time
to_ri_cal_date_time_value.end_of_day.to_datetime
end
-
+
def for_occurrence(occurrence)
if occurrence.start_of_day?
- occurrence.to_ri_cal_date_value(timezone_finder)
+ occurrence.to_ri_cal_date_value(timezone_finder)
else
occurrence.for_parent(timezone_finder)
end
View
35 lib/ri_cal/property_value/date_time.rb
@@ -66,7 +66,7 @@ def inspect # :nodoc:
# Returns the value of the receiver as an RFC 2445 iCalendar string
def value
if @date_time_value
- @date_time_value.strftime("%Y%m%dT%H%M%S#{tzid == "UTC" ? "Z" : ""}")
+ "#{@date_time_value.ical_str}#{tzid == "UTC" ? "Z" : ""}"
else
nil
end
@@ -85,16 +85,18 @@ def value=(val) # :nodoc:
when nil
@date_time_value = nil
when String
- @date_time_value = ::DateTime.parse(val)
+ @date_time_value = FastDateTime.from_date_time(::DateTime.parse(val))
if val =~/Z/
self.tzid = 'UTC'
else
@tzid ||= :floating
end
- when ::DateTime
+ when FastDateTime
@date_time_value = val
+ when ::DateTime
+ @date_time_value = FastDateTime.from_date_time(val)
when ::Date, ::Time
- @date_time_value = ::DateTime.parse(val.to_s)
+ @date_time_value = FastDateTime.from_date_time(::DateTime.parse(val.to_s))
end
reset_cached_values
end
@@ -173,7 +175,11 @@ def params
# Compare the receiver with another object which must respond to the to_datetime message
# The comparison is done using the Ruby DateTime representations of the two objects
def <=>(other)
- @date_time_value <=> other.to_datetime
+ other.cmp_fast_date_time_value(@date_time_value)
+ end
+
+ def cmp_fast_date_time_value(other)
+ other <=> @date_time_value
end
# Determine if the receiver and other are in the same month
@@ -181,12 +187,21 @@ def in_same_month_as?(other)
[other.year, other.month] == [year, month]
end
+ def with_date_time_value(date_time_value)
+ PropertyValue::DateTime.new(
+ timezone_finder,
+ :value => date_time_value,
+ :params => (params),
+ :tzid => tzid
+ )
+ end
+
def nth_wday_in_month(n, which_wday) #:nodoc:
- @date_time_value.nth_wday_in_month(n, which_wday, self)
+ with_date_time_value(@date_time_value.nth_wday_in_month(n, which_wday))
end
def nth_wday_in_year(n, which_wday) #:nodoc:
- @date_time_value.nth_wday_in_year(n, which_wday, self)
+ with_date_time_value(@date_time_value.nth_wday_in_year(n, which_wday))
end
def self.civil(year, month, day, hour, min, sec, offset, start, params) #:nodoc:
@@ -273,12 +288,12 @@ def to_ri_cal_date_or_date_time_value(timezone_finder = nil) #:nodoc:
# Return a Date property for this DateTime
def to_ri_cal_date_value(timezone_finder=nil)
- PropertyValue::Date.new(timezone_finder, :value => @date_time_value.strftime("%Y%m%d"))
+ PropertyValue::Date.new(timezone_finder, :value => @date_time_value.ical_date_str)
end
# Return the Ruby DateTime representation of the receiver
def to_datetime #:nodoc:
- @date_time_value
+ @date_time_value.to_datetime
end
# Returns a ruby DateTime object representing the receiver.
@@ -302,7 +317,7 @@ def to_zulu_time
# of the International Date Line
def to_zulu_occurrence_range_start_time
if floating?
- utc.advance(:hours => -12).to_datetime
+ @date_time_value.advance(:hours => -12, :offset => 0).to_datetime
else
to_zulu_time
end
View
38 lib/ri_cal/property_value/date_time/time_machine.rb
@@ -5,32 +5,10 @@ class DateTime
#
# Methods for DateTime which support getting values at different point in time.
module TimeMachine
- def compute_change(d, options) # :nodoc:
- ::DateTime.civil(
- options[:year] || d.year,
- options[:month] || d.month,
- options[:day] || d.day,
- options[:hour] || d.hour,
- options[:min] || (options[:hour] ? 0 : d.min),
- options[:sec] || ((options[:hour] || options[:min]) ? 0 : d.sec),
- options[:offset] || d.offset,
- options[:start] || d.start
- )
- end
-
- def compute_advance(d, options) # :nodoc:
- months_advance = (options[:years] || 0) * 12 + (options[:months] || 0)
- d = d >> months_advance unless months_advance == 0
- days_advance = (options[:weeks] || 0) * 7 + (options[:days] || 0)
- d = d + days_advance unless days_advance == 0
- datetime_advanced_by_date = compute_change(@date_time_value, :year => d.year, :month => d.month, :day => d.day)
- seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
- seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date + RiCal.RationalOffset[seconds_to_advance.round]
- end
def advance(options) # :nodoc:
PropertyValue::DateTime.new(timezone_finder,
- :value => compute_advance(@date_time_value, options),
+ :value => @date_time_value.advance(options),
:tzid => @tzid,
:params =>(params ? params.dup : nil)
)
@@ -38,34 +16,34 @@ def advance(options) # :nodoc:
def change(options) # :nodoc:
PropertyValue::DateTime.new(timezone_finder,
- :value => compute_change(@date_time_value, options),
+ :value => @date_time_value.change(options),
:tzid => @tzid,
:params => (params ? params.dup : nil)
)
end
def change_sec(new_sec) #:nodoc:
- PropertyValue::DateTime.civil(self.year, self.month, self.day, self.hour, self.min, sec, self.offset, self.start, params)
+ change(:sec => new_sec)
end
def change_min(new_min) #:nodoc:
- PropertyValue::DateTime.civil(self.year, self.month, self.day, self.hour, new_min, self.sec, self.offset, self.start, params)
+ change(:min => new_min)
end
def change_hour(new_hour) #:nodoc:
- PropertyValue::DateTime.civil(self.year, self.month, self.day, new_hour, self.min, self.sec, self.offset, self.start, params)
+ change(:hour => new_hour)
end
def change_day(new_day) #:nodoc:
- PropertyValue::DateTime.civil(self.year, self.month, new_day, self.hour, self.min, self.sec, self.offset, self.start, params)
+ change(:day => new_day)
end
def change_month(new_month) #:nodoc:
- PropertyValue::DateTime.civil(self.year, new_month, self.day, self.hour, self.min, self.sec, self.offset, self.start, params)
+ change(:month => new_month)
end
def change_year(new_year) #:nodoc:
- PropertyValue::DateTime.civil(new_year, self.month, self.day, self.hour, self.min, self.sec, self.offset, self.start, params)
+ change(:year => new_year)
end
# Return a DATE-TIME property representing the receiver on a different day (if necessary) so that
View
2  lib/ri_cal/property_value/date_time/timezone_support.rb
@@ -58,7 +58,7 @@ def utc
def rational_tz_offset #:nodoc:
if has_local_timezone?
- @rational_tz_offset ||= timezone.rational_utc_offset(@date_time_value)
+ @rational_tz_offset ||= timezone.rational_utc_offset(@date_time_value.to_datetime)
else
@rational_tz_offset ||= RiCal.RationalOffset[0]
end
View
2  performance/paris_eastern/subject.rb
@@ -87,4 +87,4 @@ def run
@date_time.in_time_zone("US/Eastern")
puts "done"
end
-end
+end
View
2  performance/utah_cycling/subject.rb
@@ -52,4 +52,4 @@ def initialize(out=STDOUT)
def run
@event.occurrences
end
-end
+end
View
24 performance_data/benchmarks.out
@@ -1,36 +1,36 @@
Rehearsal ------------------------------------------------------------
Benchmark paris_eastern: start
done
- 0.510000 0.000000 0.510000 ( 0.523553)
---------------------------------------------------- total: 0.510000sec
+ 0.250000 0.000000 0.250000 ( 0.249801)
+--------------------------------------------------- total: 0.250000sec
user system total real
Benchmark paris_eastern: start
done
- 0.000000 0.000000 0.000000 ( 0.001200)
+ 0.010000 0.000000 0.010000 ( 0.000903)
Rehearsal ------------------------------------------------------------------
-Benchmark penultimate_weekday: 0.330000 0.010000 0.340000 ( 0.345082)
---------------------------------------------------------- total: 0.340000sec
+Benchmark penultimate_weekday: 0.170000 0.010000 0.180000 ( 0.172480)
+--------------------------------------------------------- total: 0.180000sec
user system total real
-Benchmark penultimate_weekday: 0.310000 0.000000 0.310000 ( 0.307988)
+Benchmark penultimate_weekday: 0.140000 0.000000 0.140000 ( 0.142145)
Rehearsal -----------------------------------------------------------
-Benchmark psm_big_enum: 7.300000 0.060000 7.360000 ( 7.415546)
--------------------------------------------------- total: 7.360000sec
+Benchmark psm_big_enum: 6.270000 0.050000 6.320000 ( 6.369630)
+-------------------------------------------------- total: 6.320000sec
user system total real
-Benchmark psm_big_enum: 6.570000 0.050000 6.620000 ( 6.668513)
+Benchmark psm_big_enum: 5.850000 0.030000 5.880000 ( 5.922861)
Rehearsal -----------------------------------------------------------
-Benchmark utah_cycling: 0.120000 0.000000 0.120000 ( 0.119998)
--------------------------------------------------- total: 0.120000sec
+Benchmark utah_cycling: 0.090000 0.000000 0.090000 ( 0.090469)
+-------------------------------------------------- total: 0.090000sec
user system total real
-Benchmark utah_cycling: 0.040000 0.000000 0.040000 ( 0.038606)
+Benchmark utah_cycling: 0.030000 0.000000 0.030000 ( 0.036789)
View
205,188 performance_data/paris_eastern.calltree
79,700 additions, 125,488 deletions not shown
View
91,640 performance_data/penultimate_weekday.calltree
37,742 additions, 53,898 deletions not shown
View
406,508 performance_data/psm_big_enum.calltree
173,988 additions, 232,520 deletions not shown
View
119,093 performance_data/utah_cycling.calltree
117,203 additions, 1,890 deletions not shown
View
6 ri_cal.gemspec
@@ -2,11 +2,11 @@
Gem::Specification.new do |s|
s.name = %q{ri_cal}
- s.version = "0.5.3"
+ s.version = "0.6.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["author=Rick DeNatale"]
- s.date = %q{2009-06-01}
+ s.date = %q{2009-06-05}
s.default_executable = %q{ri_cal}
s.description = %q{A new Ruby implementation of RFC2445 iCalendar.
@@ -19,7 +19,7 @@ A Google group for discussion of this library has been set up http://groups.goog
s.email = ["rick.denatale@gmail.com"]
s.executables = ["ri_cal"]
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt"]
- s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/ri_cal", "component_attributes/alarm.yml", "component_attributes/calendar.yml", "component_attributes/component_property_defs.yml", "component_attributes/event.yml", "component_attributes/freebusy.yml", "component_attributes/journal.yml", "component_attributes/timezone.yml", "component_attributes/timezone_period.yml", "component_attributes/todo.yml", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt", "docs/rfc2445.pdf", "lib/ri_cal.rb", "lib/ri_cal/component.rb", "lib/ri_cal/component/alarm.rb", "lib/ri_cal/component/calendar.rb", "lib/ri_cal/component/event.rb", "lib/ri_cal/component/freebusy.rb", "lib/ri_cal/component/journal.rb", "lib/ri_cal/component/t_z_info_timezone.rb", "lib/ri_cal/component/timezone.rb", "lib/ri_cal/component/timezone/daylight_period.rb", "lib/ri_cal/component/timezone/standard_period.rb", "lib/ri_cal/component/timezone/timezone_period.rb", "lib/ri_cal/component/todo.rb", "lib/ri_cal/core_extensions.rb", "lib/ri_cal/core_extensions/array.rb", "lib/ri_cal/core_extensions/array/conversions.rb", "lib/ri_cal/core_extensions/date.rb", "lib/ri_cal/core_extensions/date/conversions.rb", "lib/ri_cal/core_extensions/date_time.rb", "lib/ri_cal/core_extensions/date_time/conversions.rb", "lib/ri_cal/core_extensions/object.rb", "lib/ri_cal/core_extensions/object/conversions.rb", "lib/ri_cal/core_extensions/string.rb", "lib/ri_cal/core_extensions/string/conversions.rb", "lib/ri_cal/core_extensions/time.rb", "lib/ri_cal/core_extensions/time/calculations.rb", "lib/ri_cal/core_extensions/time/conversions.rb", "lib/ri_cal/core_extensions/time/tzid_access.rb", "lib/ri_cal/core_extensions/time/week_day_predicates.rb", "lib/ri_cal/floating_timezone.rb", "lib/ri_cal/invalid_property_value.rb", "lib/ri_cal/invalid_timezone_identifer.rb", "lib/ri_cal/occurrence_enumerator.rb", "lib/ri_cal/occurrence_period.rb", "lib/ri_cal/parser.rb", "lib/ri_cal/properties/alarm.rb", "lib/ri_cal/properties/calendar.rb", "lib/ri_cal/properties/event.rb", "lib/ri_cal/properties/freebusy.rb", "lib/ri_cal/properties/journal.rb", "lib/ri_cal/properties/timezone.rb", "lib/ri_cal/properties/timezone_period.rb", "lib/ri_cal/properties/todo.rb", "lib/ri_cal/property_value.rb", "lib/ri_cal/property_value/array.rb", "lib/ri_cal/property_value/cal_address.rb", "lib/ri_cal/property_value/date.rb", "lib/ri_cal/property_value/date_time.rb", "lib/ri_cal/property_value/date_time/additive_methods.rb", "lib/ri_cal/property_value/date_time/time_machine.rb", "lib/ri_cal/property_value/date_time/timezone_support.rb", "lib/ri_cal/property_value/duration.rb", "lib/ri_cal/property_value/geo.rb", "lib/ri_cal/property_value/integer.rb", "lib/ri_cal/property_value/occurrence_list.rb", "lib/ri_cal/property_value/period.rb", "lib/ri_cal/property_value/recurrence_rule.rb", "lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb", "lib/ri_cal/property_value/recurrence_rule/enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb", "lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/numbered_span.rb", "lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb", "lib/ri_cal/property_value/recurrence_rule/validations.rb", "lib/ri_cal/property_value/text.rb", "lib/ri_cal/property_value/uri.rb", "lib/ri_cal/property_value/utc_offset.rb", "lib/ri_cal/required_timezones.rb", "profiling/ical_files/profile3.ics", "profiling/profile1.rb", "profiling/profile2.rb", "profiling/profile3.rb", "ri_cal.gemspec", "sample_ical_files/from_ical_dot_app/test1.ics", "script/console", "script/destroy", "script/generate", "script/txt2html", "spec/ri_cal/component/alarm_spec.rb", "spec/ri_cal/component/calendar_spec.rb", "spec/ri_cal/component/event_spec.rb", "spec/ri_cal/component/freebusy_spec.rb", "spec/ri_cal/component/journal_spec.rb", "spec/ri_cal/component/t_z_info_timezone_spec.rb", "spec/ri_cal/component/timezone_spec.rb", "spec/ri_cal/component/todo_spec.rb", "spec/ri_cal/component_spec.rb", "spec/ri_cal/core_extensions/string/conversions_spec.rb", "spec/ri_cal/core_extensions/time/calculations_spec.rb", "spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb", "spec/ri_cal/occurrence_enumerator_spec.rb", "spec/ri_cal/parser_spec.rb", "spec/ri_cal/property_value/date_spec.rb", "spec/ri_cal/property_value/date_time_spec.rb", "spec/ri_cal/property_value/duration_spec.rb", "spec/ri_cal/property_value/occurrence_list_spec.rb", "spec/ri_cal/property_value/period_spec.rb", "spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb", "spec/ri_cal/property_value/recurrence_rule_spec.rb", "spec/ri_cal/property_value/text_spec.rb", "spec/ri_cal/property_value/utc_offset_spec.rb", "spec/ri_cal/property_value_spec.rb", "spec/ri_cal/required_timezones_spec.rb", "spec/ri_cal_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem_loader/load_active_support.rb", "tasks/gem_loader/load_tzinfo_gem.rb", "tasks/ri_cal.rake", "tasks/spec.rake"]
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/ri_cal", "component_attributes/alarm.yml", "component_attributes/calendar.yml", "component_attributes/component_property_defs.yml", "component_attributes/event.yml", "component_attributes/freebusy.yml", "component_attributes/journal.yml", "component_attributes/timezone.yml", "component_attributes/timezone_period.yml", "component_attributes/todo.yml", "copyrights.txt", "docs/draft-ietf-calsify-2446bis-08.txt", "docs/draft-ietf-calsify-rfc2445bis-09.txt", "docs/incrementers.txt", "docs/rfc2445.pdf", "lib/ri_cal.rb", "lib/ri_cal/component.rb", "lib/ri_cal/component/alarm.rb", "lib/ri_cal/component/calendar.rb", "lib/ri_cal/component/event.rb", "lib/ri_cal/component/freebusy.rb", "lib/ri_cal/component/journal.rb", "lib/ri_cal/component/t_z_info_timezone.rb", "lib/ri_cal/component/timezone.rb", "lib/ri_cal/component/timezone/daylight_period.rb", "lib/ri_cal/component/timezone/standard_period.rb", "lib/ri_cal/component/timezone/timezone_period.rb", "lib/ri_cal/component/todo.rb", "lib/ri_cal/core_extensions.rb", "lib/ri_cal/core_extensions/array.rb", "lib/ri_cal/core_extensions/array/conversions.rb", "lib/ri_cal/core_extensions/date.rb", "lib/ri_cal/core_extensions/date/conversions.rb", "lib/ri_cal/core_extensions/date_time.rb", "lib/ri_cal/core_extensions/date_time/conversions.rb", "lib/ri_cal/core_extensions/object.rb", "lib/ri_cal/core_extensions/object/conversions.rb", "lib/ri_cal/core_extensions/string.rb", "lib/ri_cal/core_extensions/string/conversions.rb", "lib/ri_cal/core_extensions/time.rb", "lib/ri_cal/core_extensions/time/calculations.rb", "lib/ri_cal/core_extensions/time/conversions.rb", "lib/ri_cal/core_extensions/time/tzid_access.rb", "lib/ri_cal/core_extensions/time/week_day_predicates.rb", "lib/ri_cal/fast_date_time.rb", "lib/ri_cal/floating_timezone.rb", "lib/ri_cal/invalid_property_value.rb", "lib/ri_cal/invalid_timezone_identifer.rb", "lib/ri_cal/occurrence_enumerator.rb", "lib/ri_cal/occurrence_period.rb", "lib/ri_cal/parser.rb", "lib/ri_cal/properties/alarm.rb", "lib/ri_cal/properties/calendar.rb", "lib/ri_cal/properties/event.rb", "lib/ri_cal/properties/freebusy.rb", "lib/ri_cal/properties/journal.rb", "lib/ri_cal/properties/timezone.rb", "lib/ri_cal/properties/timezone_period.rb", "lib/ri_cal/properties/todo.rb", "lib/ri_cal/property_value.rb", "lib/ri_cal/property_value/array.rb", "lib/ri_cal/property_value/cal_address.rb", "lib/ri_cal/property_value/date.rb", "lib/ri_cal/property_value/date_time.rb", "lib/ri_cal/property_value/date_time/additive_methods.rb", "lib/ri_cal/property_value/date_time/time_machine.rb", "lib/ri_cal/property_value/date_time/timezone_support.rb", "lib/ri_cal/property_value/duration.rb", "lib/ri_cal/property_value/geo.rb", "lib/ri_cal/property_value/integer.rb", "lib/ri_cal/property_value/occurrence_list.rb", "lib/ri_cal/property_value/period.rb", "lib/ri_cal/property_value/recurrence_rule.rb", "lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb", "lib/ri_cal/property_value/recurrence_rule/enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb", "lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb", "lib/ri_cal/property_value/recurrence_rule/numbered_span.rb", "lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb", "lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb", "lib/ri_cal/property_value/recurrence_rule/validations.rb", "lib/ri_cal/property_value/text.rb", "lib/ri_cal/property_value/uri.rb", "lib/ri_cal/property_value/utc_offset.rb", "lib/ri_cal/required_timezones.rb", "performance/paris_eastern/subject.rb", "performance/penultimate_weekday/subject.rb", "performance/psm_big_enum/ical.ics", "performance/psm_big_enum/subject.rb", "performance/utah_cycling/subject.rb", "ri_cal.gemspec", "sample_ical_files/from_ical_dot_app/test1.ics", "script/benchmark_subject", "script/console", "script/destroy", "script/generate", "script/profile_subject", "script/txt2html", "spec/ri_cal/component/alarm_spec.rb", "spec/ri_cal/component/calendar_spec.rb", "spec/ri_cal/component/event_spec.rb", "spec/ri_cal/component/freebusy_spec.rb", "spec/ri_cal/component/journal_spec.rb", "spec/ri_cal/component/t_z_info_timezone_spec.rb", "spec/ri_cal/component/timezone_spec.rb", "spec/ri_cal/component/todo_spec.rb", "spec/ri_cal/component_spec.rb", "spec/ri_cal/core_extensions/string/conversions_spec.rb", "spec/ri_cal/core_extensions/time/calculations_spec.rb", "spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb", "spec/ri_cal/fast_date_time_spec.rb", "spec/ri_cal/occurrence_enumerator_spec.rb", "spec/ri_cal/parser_spec.rb", "spec/ri_cal/property_value/date_spec.rb", "spec/ri_cal/property_value/date_time_spec.rb", "spec/ri_cal/property_value/duration_spec.rb", "spec/ri_cal/property_value/occurrence_list_spec.rb", "spec/ri_cal/property_value/period_spec.rb", "spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb", "spec/ri_cal/property_value/recurrence_rule_spec.rb", "spec/ri_cal/property_value/text_spec.rb", "spec/ri_cal/property_value/utc_offset_spec.rb", "spec/ri_cal/property_value_spec.rb", "spec/ri_cal/required_timezones_spec.rb", "spec/ri_cal_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/gem_loader/load_active_support.rb", "tasks/gem_loader/load_tzinfo_gem.rb", "tasks/ri_cal.rake", "tasks/spec.rake"]
s.has_rdoc = true
s.homepage = %q{http://ri-cal.rubyforge.org/}
s.rdoc_options = ["--main", "README.txt"]
View
3  spec/ri_cal/component/event_spec.rb
@@ -267,7 +267,8 @@
it "should be the utc time of the start of the day of dtstart in the earliest timezone for a date" do
event = RiCal.Event {|e| e.dtstart = "20090525"}
- event.zulu_occurrence_range_start_time.should == DateTime.civil(2009,05,24,12,0,0,0)
+ result = event.zulu_occurrence_range_start_time
+ result.should == DateTime.civil(2009,05,24,12,0,0,0)
end
it "should be the utc time of the dtstart in the earliest timezone if dtstart is a floating datetime" do
View
2  spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb
@@ -7,7 +7,7 @@
describe ".nth_wday_in_month" do
it "should return Feb 28, 2005 for the 4th Monday for a date in February 2005" do
expected = RiCal::PropertyValue::Date.new(nil, :value => "20050228")
- it =Date.parse("Feb 7, 2005").nth_wday_in_month(4, 1)
+ it = Date.parse("Feb 7, 2005").nth_wday_in_month(4, 1)
it.should == expected
end
end
View
67 spec/ri_cal/fast_date_time_spec.rb
@@ -0,0 +1,67 @@
+#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
+
+require File.join(File.dirname(__FILE__), %w[.. spec_helper])
+
+module RiCal
+
+ describe RiCal::FastDateTime do
+ context "#==" do
+ it "should detect equal FastDateTimes" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).should ==
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0)
+ end
+
+ it "should detect unequal FastDateTimes" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).should_not ==
+ FastDateTime.new(2009, 5, 29, 19, 3, 10, 0)
+ end
+
+ context "#advance" do
+ it "should advance one second" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:seconds => 1).should ==
+ FastDateTime.new(2009, 5, 29, 19, 3, 1, 0)
+ end
+
+ it "should advance minus one second" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:seconds => -1).should ==
+ FastDateTime.new(2009, 5, 29, 19, 2, 59, 0)
+ end
+
+ it "should advance 70 seconds" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:seconds => 70).should ==
+ FastDateTime.new(2009, 5, 29, 19, 4, 10, 0)
+ end
+
+ it "should advance -70 seconds" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:seconds => -70).should ==
+ FastDateTime.new(2009, 5, 29, 19, 1, 50, 0)
+ end
+
+ it "should advance one minute" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:minutes => 1).should ==
+ FastDateTime.new(2009, 5, 29, 19, 4, 0, 0)
+ end
+
+ it "should advance minus one minute" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:minutes => -1).should ==
+ FastDateTime.new(2009, 5, 29, 19, 2, 0, 0)
+ end
+
+ it "should advance 70 minutes" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:minutes => 70).should ==
+ FastDateTime.new(2009, 5, 29, 20, 13, 0, 0)
+ end
+
+ it "should advance -70 minutes" do
+ FastDateTime.new(2009, 5, 29, 19, 3, 0, 0).advance(:minutes => -70).should ==
+ FastDateTime.new(2009, 5, 29, 17, 53, 0, 0)
+ end
+
+ it "should advance properly over a date" do
+ FastDateTime.new(2009, 5, 29, 23, 3, 0, 0).advance(:minutes => 70).should ==
+ FastDateTime.new(2009, 5, 30, 0, 13, 0, 0)
+ end
+ end
+ end
+ end
+end
View
686 spec/ri_cal/occurrence_enumerator_spec.rb
@@ -55,27 +55,20 @@ def mock_enumerator(name, next_occurrence)
result.should == Fr13UnboundedZuluExpectedFive
end
- end
- end
-
- describe ".occurrences" do
- before(:each) do
- @it = RiCal.parse_string(Fr13Unbounded_Zulu).first
- end
-
- describe "with :starting specified" do
- it "should exclude dates before :starting" do
- result = @it.occurrences(:starting => Fr13UnboundedZuluExpectedFive[1].dtstart,
- :before => Fr13UnboundedZuluExpectedFive[-1].dtstart)
- result.map{|o|o.dtstart}.should == Fr13UnboundedZuluExpectedFive[1..-2].map{|e| e.dtstart}
+ describe "with :starting specified" do
+ it "should exclude dates before :starting" do
+ result = @it.occurrences(:starting => Fr13UnboundedZuluExpectedFive[1].dtstart,
+ :before => Fr13UnboundedZuluExpectedFive[-1].dtstart)
+ result.map{|o|o.dtstart}.should == Fr13UnboundedZuluExpectedFive[1..-2].map{|e| e.dtstart}
+ end
end
- end
- describe "with :before specified" do
- it "should exclude dates after :before" do
- result = @it.occurrences(:before => Fr13UnboundedZuluExpectedFive[3].dtstart,
- :count => 5)
- result.map{|o|o.dtstart}.should == Fr13UnboundedZuluExpectedFive[0..2].map{|e| e.dtstart}
+ describe "with :before specified" do
+ it "should exclude dates after :before" do
+ result = @it.occurrences(:before => Fr13UnboundedZuluExpectedFive[3].dtstart,
+ :count => 5)
+ result.map{|o|o.dtstart}.should == Fr13UnboundedZuluExpectedFive[0..2].map{|e| e.dtstart}
+ end
end
end
end
@@ -99,6 +92,336 @@ def mock_enumerator(name, next_occurrence)
end
end
+
+ describe "#zulu_occurrence_range" do
+ context "For an unbounded recurring event" do
+ before(:each) do
+ @event = RiCal.Event do |e|
+ e.dtstart = "TZID=America/New_York:20090525T143500"
+ e.dtend = "TZID=America/New_York:20090525T153500"
+ e.add_rrule("FREQ=DAILY")
+ end
+ end
+
+ it "should not be bounded" do
+ @event.should_not be_bounded
+ end
+
+ it "should return an array with the first dtstart and nil" do
+ @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), nil]
+ end
+ end
+
+ context "For a bounded recurring event" do
+ before(:each) do
+ @event = RiCal.Event do |e|
+ e.dtstart = "TZID=America/New_York:20090525T143500"
+ e.dtend = "TZID=America/New_York:20090525T153500"
+ e.add_rrule("FREQ=DAILY;COUNT=3")
+ end
+ end
+
+ it "should return an array with the first dtstart last dtend converted to utc" do
+ @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), DateTime.civil(2009,5,27,19,35,00, 0)]
+ end
+ end
+
+ context "For an event with no recurrence rules" do
+ context "with a non-floating dtstart and dtend" do
+ before(:each) do
+ @event = RiCal.Event do |e|
+ e.dtstart = "TZID=America/New_York:20090525T143500"
+ e.dtend = "TZID=America/New_York:20090525T153500"
+ end
+ end
+
+ it "should return an array with dtstart and dtend converted to zulu time" do
+ @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), DateTime.civil(2009,5,25,19,35,00, 0)]
+ end
+ end
+ context "with a floating dtstart and dtend" do
+ before(:each) do
+ @event = RiCal.Event do |e|
+ e.dtstart = "20090525T143500"
+ e.dtend = "20090525T153500"
+ end
+ end
+
+ it "should return an array with dtstart in the first timezone and dtend in the last time zone converted to zulu time" do
+ @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,2,35,00, 0), DateTime.civil(2009,5,26,3,35,00, 0)]
+ end
+ end
+ end
+ end
+
+ context "Ticket #4 from paulsm" do
+ it "should produce 4 occurrences" do
+ cal = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VCALENDAR
+ METHOD:PUBLISH
+ PRODID:-//Apple Inc.//iCal 3.0//EN
+ CALSCALE:GREGORIAN
+ X-WR-CALNAME:Australian32Holidays
+ X-WR-CALDESC:Australian Public Holidays. Compiled from http://www.indust
+ rialrelations.nsw.gov.au/holidays/default.html and the links for the oth
+ er states at the bottom of that page
+ X-WR-RELCALID:AC1E4CE8-6690-49F6-A144-2F8891DFFD8D
+ VERSION:2.0
+ X-WR-TIMEZONE:Australia/Sydney
+ BEGIN:VEVENT
+ SEQUENCE:8
+ TRANSP:OPAQUE
+ UID:5B5579F3-2137-11D7-B491-00039301B0C2
+ DTSTART;VALUE=DATE:20020520
+ DTSTAMP:20060602T045619Z
+ SUMMARY:Adelaide Cup Carnival and Volunteers Day (SA)
+ EXDATE;VALUE=DATE:20060515
+ CREATED:20080916T000924Z
+ DTEND;VALUE=DATE:20020521
+ RRULE:FREQ=YEARLY;INTERVAL=1;UNTIL=20070520;BYMONTH=5;BYDAY=3MO
+ END:VEVENT
+ END:VCALENDAR
+ ENDCAL
+ cal.first.events.first.occurrences.length.should == 4
+ end
+ end
+
+ context "Ticket #2 from paulsm" do
+ before(:each) do
+ cals = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VCALENDAR
+ X-WR-TIMEZONE:America/New_York
+ PRODID:-//Apple Inc.//iCal 3.0//EN
+ CALSCALE:GREGORIAN
+ X-WR-CALNAME:test
+ VERSION:2.0
+ X-WR-RELCALID:1884C7F8-BC8E-457F-94AC-297871967D5E
+ X-APPLE-CALENDAR-COLOR:#2CA10B
+ BEGIN:VTIMEZONE
+ TZID:US/Eastern
+ BEGIN:DAYLIGHT
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ DTSTART:20070311T020000
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+ TZNAME:EDT
+ END:DAYLIGHT
+ BEGIN:STANDARD
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ DTSTART:20071104T020000
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+ TZNAME:EST
+ END:STANDARD
+ END:VTIMEZONE
+ BEGIN:VEVENT
+ SEQUENCE:5
+ TRANSP:OPAQUE
+ UID:00481E53-9258-4EA7-9F8D-947D3041A3F2
+ DTSTART;TZID=US/Eastern:20090224T090000
+ DTSTAMP:20090225T000908Z
+ SUMMARY:Test Event
+ CREATED:20090225T000839Z
+ DTEND;TZID=US/Eastern:20090224T100000
+ RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z
+ END:VEVENT
+ END:VCALENDAR
+ ENDCAL
+ @event = cals.first.events.first
+ end
+
+
+ it "the event should be enumerable" do
+ lambda {@event.occurrences}.should_not raise_error
+ end
+ end
+
+ context "Lighthouse bug #3" do
+ before(:each) do
+ cals = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VCALENDAR
+ VERSION:2.0
+ PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
+ BEGIN:VTIMEZONE
+ TZID:/mozilla.org/20070129_1/Europe/Paris
+ X-LIC-LOCATION:Europe/Paris
+ BEGIN:DAYLIGHT
+ TZOFFSETFROM:+0100
+ TZOFFSETTO:+0200
+ TZNAME:CEST
+ DTSTART:19700329T020000
+ RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
+ END:DAYLIGHT
+ BEGIN:STANDARD
+ TZOFFSETFROM:+0200
+ TZOFFSETTO:+0100
+ TZNAME:CET
+ DTSTART:19701025T030000
+ RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
+ END:STANDARD
+ END:VTIMEZONE
+ BEGIN:VEVENT
+ CREATED:20070606T141629Z
+ LAST-MODIFIED:20070606T154611Z
+ DTSTAMP:20070607T120859Z
+ UID:5d1ae55f-3910-4de9-8b65-d652768fb2f2
+ SUMMARY:Lundi de Pâques
+ DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070409
+ DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070410
+ CATEGORIES:Jours fériés
+ END:VEVENT
+ END:VCALENDAR
+ ENDCAL
+ @event = cals.first.events.first
+ end
+
+ it "should be able to enumerate occurrences" do
+ @event.occurrences.should == [@event]
+ end
+ end
+
+ context "An event with a DATE dtstart, Ticket #6" do
+ before(:each) do
+ cal = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VCALENDAR
+ PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
+ VERSION:2.0
+ BEGIN:VEVENT
+ CREATED:20090520T092032Z
+ LAST-MODIFIED:20090520T092052Z
+ DTSTAMP:20090520T092032Z
+ UID:d41c124a-65c3-400e-bd04-1d2ee7b98352
+ SUMMARY:event2
+ RRULE:FREQ=MONTHLY;INTERVAL=1
+ DTSTART;VALUE=DATE:20090603
+ DTEND;VALUE=DATE:20090604
+ TRANSP:TRANSPARENT
+ END:VEVENT
+ END:VCALENDAR
+ ENDCAL
+ @occurrences = cal.first.events.first.occurrences(
+ :after => Date.parse('01/01/1990'),
+ :before => Date.parse("01/01/2010")
+ )
+ end
+
+ it "should produce the right dtstart values" do
+ @occurrences.map {|o| o.dtstart}.should == [
+ Date.parse("2009-06-03"),
+ Date.parse("2009-07-03"),
+ Date.parse("2009-08-03"),
+ Date.parse("2009-09-03"),
+ Date.parse("2009-10-03"),
+ Date.parse("2009-11-03"),
+ Date.parse("2009-12-03")
+ ]
+ end
+
+ it "should produce events whose dtstarts are all dates" do
+ @occurrences.all? {|o| o.dtstart.class == ::Date}.should be_true
+ end
+
+ it "should produce the right dtend values" do
+ @occurrences.map {|o| o.dtend}.should == [
+ Date.parse("2009-06-04"),
+ Date.parse("2009-07-04"),
+ Date.parse("2009-08-04"),
+ Date.parse("2009-09-04"),
+ Date.parse("2009-10-04"),
+ Date.parse("2009-11-04"),
+ Date.parse("2009-12-04")
+ ]
+ end
+
+ it "should produce events whose dtstends are all dates" do
+ @occurrences.all? {|o| o.dtend.class == ::Date}.should be_true
+ end
+ end
+ context "bounded? bug" do
+ before(:each) do
+ events = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VEVENT
+ EXDATE:20090114T163000
+ EXDATE:20090128T163000
+ EXDATE:20090121T163000
+ EXDATE:20090211T163000
+ EXDATE:20090204T163000
+ EXDATE:20090218T163000
+ TRANSP:OPAQUE
+ DTSTAMP;VALUE=DATE-TIME:20090107T024340Z
+ CREATED;VALUE=DATE-TIME:20090107T024012Z
+ DTEND;TZID=US/Mountain;VALUE=DATE-TIME:20090114T180000
+ DTSTART;TZID=US/Mountain;VALUE=DATE-TIME:20090114T163000
+ UID:15208112-E0FA-4A7C-954C-CFDF19D1B0E7
+ RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20090219T065959Z
+ SUMMARY:Wild Rose XC/Skate Training Series
+ SEQUENCE:11
+ LOCATION:Mountain Dell Golf Course
+ END:VEVENT
+ ENDCAL
+ @event = events.first
+ end
+
+ it "should be able to enumerate occurrences" do
+ @event.should be_bounded
+ end
+ end
+
+ context "EXDATES with timezones bug" do
+ before(:each) do
+ cals = RiCal.parse_string rectify_ical <<-ENDCAL
+ BEGIN:VCALENDAR
+ METHOD:PUBLISH
+ PRODID:-//Apple Inc.//iCal 3.0//EN
+ CALSCALE:GREGORIAN
+ X-WR-CALNAME:Utah Cycling
+ X-WR-RELCALID:BF579011-36BF-49C6-8C7D-E96F03DE8055
+ VERSION:2.0
+ X-WR-TIMEZONE:US/Mountain
+ BEGIN:VTIMEZONE
+ TZID:US/Mountain
+ BEGIN:DAYLIGHT
+ TZOFFSETFROM:-0700
+ TZOFFSETTO:-0600
+ DTSTART:20070311T020000
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+ TZNAME:MDT
+ END:DAYLIGHT
+ BEGIN:STANDARD
+ TZOFFSETFROM:-0600
+ TZOFFSETTO:-0700
+ DTSTART:20071104T020000
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+ TZNAME:MST
+ END:STANDARD
+ END:VTIMEZONE
+ BEGIN:VEVENT
+ SEQUENCE:11
+ TRANSP:OPAQUE
+ UID:15208112-E0FA-4A7C-954C-CFDF19D1B0E7
+ DTSTART;TZID=US/Mountain:20090114T163000
+ DTSTAMP:20090107T024340Z
+ SUMMARY:Wild Rose XC/Skate Training Series
+ EXDATE;TZID=US/Mountain:20090114T163000
+ EXDATE;TZID=US/Mountain:20090128T163000
+ EXDATE;TZID=US/Mountain:20090121T163000
+ EXDATE;TZID=US/Mountain:20090211T163000
+ EXDATE;TZID=US/Mountain:20090204T163000
+ EXDATE;TZID=US/Mountain:20090218T163000
+ CREATED:20090107T024012Z
+ DTEND;TZID=US/Mountain:20090114T180000
+ LOCATION:Mountain Dell Golf Course
+ RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20090219T065959Z
+ END:VEVENT
+ END:VCALENDAR
+ ENDCAL
+ @event = cals.first.events.first
+ end
+
+ it "should have no occurrences" do
+ @event.occurrences.length.should == 0
+ end
+ end
end
describe RiCal::OccurrenceEnumerator::OccurrenceMerger do
@@ -157,7 +480,7 @@ def mock_enumerator(name, next_occurrence)
end
end
end
-
+
describe "#zulu_occurrence_range" do
end
@@ -242,332 +565,9 @@ def mock_enumerator(name, next_occurrence)
end
end
- context "Ticket #4 from paulsm" do
- it "should produce 4 occurrences" do
- cal = RiCal.parse_string <<ENDCAL
-BEGIN:VCALENDAR
-METHOD:PUBLISH
-PRODID:-//Apple Inc.//iCal 3.0//EN
-CALSCALE:GREGORIAN
-X-WR-CALNAME:Australian32Holidays
-X-WR-CALDESC:Australian Public Holidays. Compiled from http://www.indust
- rialrelations.nsw.gov.au/holidays/default.html and the links for the oth
- er states at the bottom of that page
-X-WR-RELCALID:AC1E4CE8-6690-49F6-A144-2F8891DFFD8D
-VERSION:2.0
-X-WR-TIMEZONE:Australia/Sydney
-BEGIN:VEVENT
-SEQUENCE:8
-TRANSP:OPAQUE
-UID:5B5579F3-2137-11D7-B491-00039301B0C2
-DTSTART;VALUE=DATE:20020520
-DTSTAMP:20060602T045619Z
-SUMMARY:Adelaide Cup Carnival and Volunteers Day (SA)
-EXDATE;VALUE=DATE:20060515
-CREATED:20080916T000924Z
-DTEND;VALUE=DATE:20020521
-RRULE:FREQ=YEARLY;INTERVAL=1;UNTIL=20070520;BYMONTH=5;BYDAY=3MO
-END:VEVENT
-END:VCALENDAR
-ENDCAL
- cal.first.events.first.occurrences.length.should == 4
- end
- end
-
- context "Ticket #2 from paulsm" do
- before(:each) do
- cals = RiCal.parse_string <<ENDCAL
-BEGIN:VCALENDAR
-X-WR-TIMEZONE:America/New_York
-PRODID:-//Apple Inc.//iCal 3.0//EN
-CALSCALE:GREGORIAN
-X-WR-CALNAME:test
-VERSION:2.0
-X-WR-RELCALID:1884C7F8-BC8E-457F-94AC-297871967D5E
-X-APPLE-CALENDAR-COLOR:#2CA10B
-BEGIN:VTIMEZONE
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-DTSTART:20070311T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-TZNAME:EDT
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-DTSTART:20071104T020000
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-TZNAME:EST
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-SEQUENCE:5
-TRANSP:OPAQUE
-UID:00481E53-9258-4EA7-9F8D-947D3041A3F2
-DTSTART;TZID=US/Eastern:20090224T090000
-DTSTAMP:20090225T000908Z
-SUMMARY:Test Event
-CREATED:20090225T000839Z
-DTEND;TZID=US/Eastern:20090224T100000
-RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z
-END:VEVENT
-END:VCALENDAR
-ENDCAL
- @event = cals.first.events.first
- end
- it "the event should be enumerable" do
- lambda {@event.occurrences}.should_not raise_error
- end
- end
- context "Lighthouse bug #3" do
- before(:each) do
- cals = RiCal.parse_string <<ENDCAL
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
-BEGIN:VTIMEZONE
-TZID:/mozilla.org/20070129_1/Europe/Paris
-X-LIC-LOCATION:Europe/Paris
-BEGIN:DAYLIGHT
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-TZNAME:CEST
-DTSTART:19700329T020000
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-TZNAME:CET
-DTSTART:19701025T030000
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-CREATED:20070606T141629Z
-LAST-MODIFIED:20070606T154611Z
-DTSTAMP:20070607T120859Z
-UID:5d1ae55f-3910-4de9-8b65-d652768fb2f2
-SUMMARY:Lundi de Pâques
-DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070409
-DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070410
-CATEGORIES:Jours fériés
-END:VEVENT
-END:VCALENDAR
-ENDCAL
- @event = cals.first.events.first
- end
-
- it "should be able to enumerate occurrences" do
- @event.occurrences.should == [@event]
- end
- end
-
- context "An event with a DATE dtstart, Ticket #6" do
- before(:each) do
- cal = RiCal.parse_string <<ENDCAL
-BEGIN:VCALENDAR
-PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
-VERSION:2.0
-BEGIN:VEVENT
-CREATED:20090520T092032Z
-LAST-MODIFIED:20090520T092052Z
-DTSTAMP:20090520T092032Z
-UID:d41c124a-65c3-400e-bd04-1d2ee7b98352
-SUMMARY:event2
-RRULE:FREQ=MONTHLY;INTERVAL=1
-DTSTART;VALUE=DATE:20090603
-DTEND;VALUE=DATE:20090604
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
-ENDCAL
- @occurrences = cal.first.events.first.occurrences(
- :after => Date.parse('01/01/1990'),
- :before => Date.parse("01/01/2010")
- )
- end
-
- it "should produce the right dtstart values" do
- @occurrences.map {|o| o.dtstart}.should == [
- Date.parse("2009-06-03"),
- Date.parse("2009-07-03"),
- Date.parse("2009-08-03"),
- Date.parse("2009-09-03"),
- Date.parse("2009-10-03"),
- Date.parse("2009-11-03"),
- Date.parse("2009-12-03")
- ]
- end
-
- it "should produce events whose dtstarts are all dates" do
- @occurrences.all? {|o| o.dtstart.class == ::Date}.should be_true
- end
-
- it "should produce the right dtend values" do
- @occurrences.map {|o| o.dtend}.should == [
- Date.parse("2009-06-04"),
- Date.parse("2009-07-04"),
- Date.parse("2009-08-04"),
- Date.parse("2009-09-04"),
- Date.parse("2009-10-04"),
- Date.parse("2009-11-04"),
- Date.parse("2009-12-04")
- ]
- end
- it "should produce events whose dtstends are all dates" do
- @occurrences.all? {|o| o.dtend.class == ::Date}.should be_true
- end
- end
- context "bounded? bug" do
- before(:each) do
- events = RiCal.parse_string rectify_ical <<-ENDCAL
- BEGIN:VEVENT
- EXDATE:20090114T163000
- EXDATE:20090128T163000
- EXDATE:20090121T163000
- EXDATE:20090211T163000
- EXDATE:20090204T163000
- EXDATE:20090218T163000
- TRANSP:OPAQUE
- DTSTAMP;VALUE=DATE-TIME:20090107T024340Z
- CREATED;VALUE=DATE-TIME:20090107T024012Z
- DTEND;TZID=US/Mountain;VALUE=DATE-TIME:20090114T180000
- DTSTART;TZID=US/Mountain;VALUE=DATE-TIME:20090114T163000
- UID:15208112-E0FA-4A7C-954C-CFDF19D1B0E7
- RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20090219T065959Z
- SUMMARY:Wild Rose XC/Skate Training Series
- SEQUENCE:11
- LOCATION:Mountain Dell Golf Course
- END:VEVENT
- ENDCAL
- @event = events.first
- end
-
- it "should be able to enumerate occurrences" do
- @event.should be_bounded
- end
- end
-
- context "EXDATES with timezones bug" do
- before(:each) do
- cals = RiCal.parse_string rectify_ical <<-ENDCAL
- BEGIN:VCALENDAR
- METHOD:PUBLISH
- PRODID:-//Apple Inc.//iCal 3.0//EN
- CALSCALE:GREGORIAN
- X-WR-CALNAME:Utah Cycling
- X-WR-RELCALID:BF579011-36BF-49C6-8C7D-E96F03DE8055
- VERSION:2.0
- X-WR-TIMEZONE:US/Mountain
- BEGIN:VTIMEZONE
- TZID:US/Mountain
- BEGIN:DAYLIGHT
- TZOFFSETFROM:-0700
- TZOFFSETTO:-0600
- DTSTART:20070311T020000
- RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
- TZNAME:MDT
- END:DAYLIGHT
- BEGIN:STANDARD
- TZOFFSETFROM:-0600
- TZOFFSETTO:-0700
- DTSTART:20071104T020000
- RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
- TZNAME:MST
- END:STANDARD
- END:VTIMEZONE
- BEGIN:VEVENT
- SEQUENCE:11
- TRANSP:OPAQUE
- UID:15208112-E0FA-4A7C-954C-CFDF19D1B0E7
- DTSTART;TZID=US/Mountain:20090114T163000
- DTSTAMP:20090107T024340Z
- SUMMARY:Wild Rose XC/Skate Training Series
- EXDATE;TZID=US/Mountain:20090114T163000
- EXDATE;TZID=US/Mountain:20090128T163000
- EXDATE;TZID=US/Mountain:20090121T163000
- EXDATE;TZID=US/Mountain:20090211T163000
- EXDATE;TZID=US/Mountain:20090204T163000
- EXDATE;TZID=US/Mountain:20090218T163000
- CREATED:20090107T024012Z
- DTEND;TZID=US/Mountain:20090114T180000
- LOCATION:Mountain Dell Golf Course
- RRULE:FREQ=WEEKLY;INTERVAL=1;UNTIL=20090219T065959Z
- END:VEVENT
- END:VCALENDAR
- ENDCAL
- @event = cals.first.events.first
- end
-
- it "should have no occurrences" do
- @event.occurrences.length.should == 0
- end
- end
-
-
- describe "#zulu_occurrence_range" do
- context "For an unbounded recurring event" do
- before(:each) do
- @event = RiCal.Event do |e|
- e.dtstart = "TZID=America/New_York:20090525T143500"
- e.dtend = "TZID=America/New_York:20090525T153500"
- e.add_rrule("FREQ=DAILY")
- end
-
- it "should return an array with the first dtstart and nil" do
- @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), nil]
- end
- end
- end
-
- context "For a bounded recurring event" do
- before(:each) do
- @event = RiCal.Event do |e|
- e.dtstart = "TZID=America/New_York:20090525T143500"
- e.dtend = "TZID=America/New_York:20090525T153500"
- e.add_rrule("FREQ=DAILY;COUNT=3")
- end
-
- it "should return an array with the first dtstart last dtend converted to utc" do
- @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), DateTime.civil(2009,5,27,19,35,00, 0)]
- end
- end
- end
-
- context "For an event with no recurrence rules" do
- context "with a non-floating dtstart and dtend" do
- before(:each) do
- @event = RiCal.Event do |e|
- e.dtstart = "TZID=America/New_York:20090525T143500"
- e.dtend = "TZID=America/New_York:20090525T153500"
- end
- end
-
- it "should return an array with dtstart and dtend converted to zulu time" do
- @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,18,35,00, 0), DateTime.civil(2009,5,25,19,35,00, 0)]
- end
- end
- context "with a floating dtstart and dtend" do
- before(:each) do
- @event = RiCal.Event do |e|
- e.dtstart = "20090525T143500"
- e.dtend = "20090525T153500"
- end
- end
-
- it "should return an array with dtstart in the first timezone and dtend in the last time zone converted to zulu time" do
- @event.zulu_occurrence_range.should == [DateTime.civil(2009,5,25,2,35,00, 0), DateTime.civil(2009,5,26,3,35,00, 0)]
- end
- end
- end
- end
-
end

0 comments on commit b02493b

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