rubyredrick-ri_cal 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,8 +1,12 @@
1
+ === 0.0.7
2
+ * Fixed a bug relating to properly recognizing ActiveRecord::TimeWithZone
3
+ * DATETIME propertyvalues will now return an instance of TimeWithZone instead of DateTime when
4
+ activesupport is present, and it is appropriate. See the README for details
1
5
  === 0.0.6
2
6
  * Added rake tasks to run specs with either the tzinfo gem or activesupport (<=2.2)
3
7
  * Default rake task now runs both of these
4
- === 0.0.5
5
- * Fixed a bug in occurrence enumeration reported by paulsm on github
8
+ === 0.0.5
9
+ * Fixed a bug in occurrence enumeration reported by paulsm on github
6
10
  === 0.0.4
7
11
  * Fixed a bug in imported timezones reported by paulsm on github
8
12
  === 0.0.3
data/README.txt CHANGED
@@ -181,6 +181,43 @@ or the equivalent
181
181
 
182
182
  event.dtstart = Time.parse("1/1/2010 00:00:00").set_tzid(:floating)
183
183
 
184
+ === RiCal produced Calendars and Tzinfo
185
+
186
+ Calendars created by the RiCal Builder DSL use TZInfo as a source of time zone definition
187
+ information. RFC 2445 does not specify standard names for time zones, so each time zone identifier
188
+ (tzid) within an icalendar data stream must correspond to a VTIMEZONE component in that data
189
+ stream.
190
+
191
+ When an RiCal calendar is exported to an icalendar data stream, the needed VTIMEZONE components
192
+ will be generated. In addition a parameter is added to the PRODID property of the calendar which
193
+ identifies that the source of tzids is tzinfo. For purposes of this documentation such a calendar
194
+ is called a tzinfo calendar.
195
+
196
+ When RiCal imports an icalendar data stream produced by another library or application, such as
197
+ Apple's ical.app, or Google mail, it will be recognized as not being a non-tzinfo calendar, and any
198
+ tzids will be resolved using the included VTIMEZONEs. Note that these calendars may well use tzids
199
+ which are not recognizable by the tzinfo gem or by the similar code provided by ActiveSupport,
200
+ so care is needed in using them.
201
+
202
+ === Ruby values of DATETIME properties
203
+
204
+ The result of accessing the value of a DATETIME property (e.g. event.dtstart) depends on several
205
+ factors:
206
+
207
+ * If the property has a DATE value, then the result will be a Ruby Date object.
208
+
209
+ * Otherwise, if the property has a DATETIME value with a floating timezone, then the result will
210
+ be a Ruby DateTime object, the tzid attribute will be set to :floating, and will respond
211
+ truthily to has_floating_timezone?
212
+
213
+ * Otherwise if the value is attached to a property contained in a non-tzinfo calendar, or if the
214
+ ActiveSupport gem is not loaded, then the result will be a Ruby DateTime object, with the proper
215
+ offset from UTC, and with the tzid property set.
216
+
217
+ * Finally, if the value is attached to a property contained in a tzinfo calendar and the
218
+ ActiveSupport gem is loaded, then the result will be an ActiveSupport::TimeWithZone with the
219
+ proper tzid.
220
+
184
221
  ==== RDATE, and EXDATE properties (Occurrence Lists)
185
222
 
186
223
  A calendar component which supports recurrence properties (e.g. Event) may have zero or more RDATE
@@ -10,8 +10,8 @@ module RiCal
10
10
  attr_reader :tz_source #:nodoc:
11
11
 
12
12
  def initialize(parent=nil, &init_block) #:nodoc:
13
- super
14
13
  @tz_source = 'TZINFO' # Until otherwise told
14
+ super
15
15
  end
16
16
 
17
17
  def self.entity_name #:nodoc:
@@ -122,21 +122,25 @@ module RiCal
122
122
  tzinfo.identifier
123
123
  end
124
124
 
125
- def date_time(ruby_time, tzid) #:nodoc:
126
- RiCal::PropertyValue::DateTime.new(calendar, :value => ruby_time, :params => {'TZID' => tzid})
125
+ def local_date_time(ruby_time, tzid) #:nodoc:
126
+ RiCal::PropertyValue::DateTime.new(calendar, :value => ruby_time.strftime("%Y%m%dT%H%M%S"), :params => {'TZID' => tzid})
127
+ end
128
+
129
+ def utc_date_time(ruby_time) #:nodoc
130
+ RiCal::PropertyValue::DateTime.new(calendar, :value => ruby_time.strftime("%Y%m%dT%H%M%SZ"))
127
131
  end
128
132
 
129
133
  def local_to_utc(utc) #:nodoc:
130
- date_time(tzinfo.local_to_utc(utc.to_ri_cal_ruby_value), 'UTC')
134
+ utc_date_time(tzinfo.local_to_utc(utc.to_ri_cal_ruby_value))
131
135
  end
132
136
 
133
137
  def utc_to_local(local) #:nodoc:
134
- date_time(tzinfo.utc_to_local(local.to_ri_cal_ruby_value), tzinfo.identifier)
138
+ local_date_time(tzinfo.utc_to_local(local.to_ri_cal_ruby_value), tzinfo.identifier)
135
139
  end
136
140
 
137
141
 
138
142
  def rational_utc_offset(local)
139
- Rational(tzinfo.period_for_local(local, true).utc_offset, 3600) / 24
143
+ Rational(tzinfo.period_for_local(local, true).utc_total_offset, 3600) / 24
140
144
  end
141
145
 
142
146
  end
@@ -17,7 +17,7 @@ module RiCal
17
17
  def swallows_local?(local, std_candidate)
18
18
  ([local.year, local.month, local.day] == [dtstart.year,dtstart.month, dtstart.day]) &&
19
19
  local >= dtstart_property &&
20
- local.advance(:seconds => (utc_total_offset - std_candidate.utc_total_offset)) < dtstart_property
20
+ local.advance(:seconds => (std_candidate.utc_total_offset - utc_total_offset)) < dtstart_property
21
21
  end
22
22
  end
23
23
  end
@@ -27,7 +27,7 @@ module RiCal
27
27
  end
28
28
 
29
29
  def utc_total_offset #:nodoc:
30
- tzoffsetfrom_property.to_seconds
30
+ tzoffsetto_property.to_seconds
31
31
  end
32
32
 
33
33
  def exrule_property #:nodoc:
@@ -31,7 +31,7 @@ module RiCal
31
31
  end
32
32
 
33
33
  autoload :Timezone, "#{File.dirname(__FILE__)}/component/timezone.rb"
34
-
34
+
35
35
  attr_accessor :imported #:nodoc:
36
36
 
37
37
  def initialize(parent=nil, &init_block) #:nodoc:
@@ -44,7 +44,7 @@ module RiCal
44
44
  end
45
45
  end
46
46
  end
47
-
47
+
48
48
  def default_tzid #:nodoc:
49
49
  if @parent
50
50
  @parent.default_tzid
@@ -52,7 +52,7 @@ module RiCal
52
52
  PropertyValue::DateTime.default_tzid
53
53
  end
54
54
  end
55
-
55
+
56
56
  def find_timezone(identifier) #:nodoc:
57
57
  if @parent
58
58
  @parent.find_timezone(identifier)
@@ -65,10 +65,18 @@ module RiCal
65
65
  end
66
66
  end
67
67
 
68
+ def tz_info_source?
69
+ if @parent
70
+ @parent.tz_info_source?
71
+ else
72
+ true
73
+ end
74
+ end
75
+
68
76
  def time_zone_for(ruby_object) #:nodoc:
69
77
  @parent.time_zone_for(ruby_object) #:nodoc:
70
78
  end
71
-
79
+
72
80
  def subcomponent_class #:nodoc:
73
81
  {}
74
82
  end
@@ -87,7 +95,7 @@ module RiCal
87
95
  def self.parse(io) #:nodoc:
88
96
  Parser.new(io).parse
89
97
  end
90
-
98
+
91
99
  def imported? #:nodoc:
92
100
  imported
93
101
  end
@@ -95,7 +103,7 @@ module RiCal
95
103
  def self.parse_string(string) #:nodoc:
96
104
  parse(StringIO.new(string))
97
105
  end
98
-
106
+
99
107
  def subcomponents #:nodoc:
100
108
  @subcomponents ||= Hash.new {|h, k| h[k] = []}
101
109
  end
@@ -137,11 +145,11 @@ module RiCal
137
145
  @x_properties ||= {}
138
146
  end
139
147
 
140
- # Add a n extended property
148
+ # Add a n extended property
141
149
  def add_x_property(name, prop)
142
150
  x_properties[name] = prop
143
151
  end
144
-
152
+
145
153
  def method_missing(selector, *args, &b) #:nodoc:
146
154
  xprop_candidate = selector.to_s
147
155
  if (match = /^x_(.+)(=?)$/.match(xprop_candidate))
@@ -202,7 +210,7 @@ module RiCal
202
210
  component.export_to(export_stream)
203
211
  end
204
212
  end
205
-
213
+
206
214
  # return a string containing the rfc2445 format of the component
207
215
  def to_s
208
216
  io = StringIO.new
@@ -17,21 +17,32 @@ module RiCal
17
17
  self.tzid = time_zone_identifier
18
18
  self
19
19
  end
20
+
21
+ # Predicate indicating whether or not the instance represents a floating time
22
+ def has_floating_timezone?
23
+ tzid == :floating
24
+ end
25
+
20
26
  end
21
27
  end
22
28
  end
23
29
 
24
30
  module TimeWithZoneExtension #:nodoc:
25
31
  def tzid
26
- time_zone.tzid.identifier
32
+ utc? ? "UTC" : time_zone.tzinfo.identifier
33
+ end
34
+
35
+ # Predicate indicating whether or not the instance represents a floating time
36
+ def has_floating_timezone?
37
+ false
38
+ end
39
+
40
+ def to_ri_cal_date_or_date_time_value(timezone_finder=nil)
41
+ ::RiCal::PropertyValue::DateTime.new(timezone_finder, :params => {"TZID" => tzid}, :value => strftime("%Y%m%dT%H%M%S"))
27
42
  end
28
43
  end
29
44
  end
30
45
 
31
- if Object.const_defined?(:ActiveSupport)
32
- as = Object.const_get(:ActiveSupport)
33
- if as.const_defined?(:TimeWithZone)
34
- twz = as.const_get(:TimeWithZone)
35
- twz.class_eval {include RiCal::TimeWithZoneExtension}
36
- end
46
+ if RiCal::TimeWithZone
47
+ RiCal::TimeWithZone.class_eval {include RiCal::TimeWithZoneExtension}
37
48
  end
@@ -4,7 +4,7 @@ module RiCal
4
4
  #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
5
5
  #
6
6
  # Time zone related methods for DateTime
7
- module TimezoneSupport
7
+ module TimezoneSupport
8
8
  # Return the timezone id of the receiver, or nil if it is a floating time
9
9
  def tzid
10
10
  @tzid == :floating ? nil : @tzid
@@ -65,6 +65,19 @@ module RiCal
65
65
  tzid == "UTC"
66
66
  end
67
67
 
68
+ # Predicate indicating whether or not the instance represents a floating time
69
+ def floating?
70
+ tzid == :floating
71
+ end
72
+
73
+ def has_valid_tzinfo_tzid? #:nodoc:
74
+ if tzid && tzid != :floating
75
+ TZInfo::Timezone.get(tzid) rescue false
76
+ else
77
+ false
78
+ end
79
+ end
80
+
68
81
  # Returns the simultaneous time in the specified zone.
69
82
  def in_time_zone(new_zone)
70
83
  new_zone = timezone_finder.find_timezone(new_zone)
@@ -16,10 +16,6 @@ module RiCal
16
16
  include TimezoneSupport
17
17
  include TimeMachine
18
18
 
19
- # def initialize(timezone_finder, options={}) #:nodoc:
20
- # super(timezone_finder ? timezone_finder : Calendar.new, options)
21
- # end
22
- #
23
19
  def self.or_date(parent, line) # :nodoc:
24
20
  if /T/.match(line[:value] || "")
25
21
  new(parent, line)
@@ -280,8 +276,12 @@ module RiCal
280
276
  end
281
277
 
282
278
  # Returns a ruby DateTime object representing the receiver.
283
- def ruby_value
284
- ::DateTime.civil(year, month, day, hour, min, sec, rational_tz_offset).set_tzid(@tzid)
279
+ def ruby_value
280
+ if has_valid_tzinfo_tzid? && RiCal::TimeWithZone && tz_info_source?
281
+ RiCal::TimeWithZone.new(utc.to_datetime, ::Time.__send__(:get_zone, @tzid))
282
+ else
283
+ ::DateTime.civil(year, month, day, hour, min, sec, rational_tz_offset).set_tzid(@tzid)
284
+ end
285
285
  end
286
286
 
287
287
  alias_method :to_ri_cal_ruby_value, :to_datetime
@@ -67,7 +67,7 @@ module RiCal
67
67
  def validate_elements # :nodoc:
68
68
  if @source_elements
69
69
  self.tzid = tzid_from_source_elements
70
- @elements = values_to_elements(@source_elements)
70
+ @elements = values_to_elements(@source_elements)
71
71
  @value = @elements.map {|prop| prop.value}
72
72
  else
73
73
  @elements = values_to_elements(@value)
@@ -132,6 +132,14 @@ module RiCal
132
132
  PropertyValue::DateTime.default_tzid
133
133
  end
134
134
  end
135
+
136
+ def tz_info_source? #:nodoc:
137
+ if timezone_finder
138
+ timezone_finder.tz_info_source?
139
+ else
140
+ true
141
+ end
142
+ end
135
143
  end
136
144
  end
137
145
 
data/lib/ri_cal.rb CHANGED
@@ -11,7 +11,7 @@ module RiCal
11
11
  autoload :OccurrenceEnumerator, "#{my_dir}/ri_cal/occurrence_enumerator.rb"
12
12
 
13
13
  # :stopdoc:
14
- VERSION = '0.0.6'
14
+ VERSION = '0.0.7'
15
15
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
16
16
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
17
17
 
@@ -120,6 +120,17 @@ module RiCal
120
120
  Component::TimezonePeriod.new(&init_block)
121
121
  end
122
122
 
123
+ if Object.const_defined?(:ActiveSupport)
124
+ as = Object.const_get(:ActiveSupport)
125
+ if as.const_defined?(:TimeWithZone)
126
+ time_with_zone = as.const_get(:TimeWithZone)
127
+ end
128
+ end
129
+
130
+ # TimeWithZone will be set to ActiveSupport::TimeWithZone if the activesupport gem is loaded
131
+ # otherwise it will be nil
132
+ TimeWithZone = time_with_zone
133
+
123
134
  # return a new Todo calendar component. If a block is provided it will will be executed in
124
135
  # the context of a builder object which can be used to initialize the properties and alarms of the
125
136
  # new Todo.
data/ri_cal.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{ri_cal}
5
- s.version = "0.0.6"
5
+ s.version = "0.0.7"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["author=Rick DeNatale"]
9
- s.date = %q{2009-05-17}
9
+ s.date = %q{2009-05-18}
10
10
  s.default_executable = %q{ri_cal}
11
11
  s.description = %q{This is an UNOFFICIAL version. The public official version will be released on RubyForge. Github will be used
12
12
  for interim versions. USE THIS VERSION AT YOUR OWN RISK.
@@ -1,5 +1,4 @@
1
1
  #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
-
3
2
  require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
3
 
5
4
  describe RiCal::Component::Event do
@@ -29,8 +28,9 @@ describe RiCal::Component::Event do
29
28
  end
30
29
 
31
30
  it "should accept a single Time and replace the existing rdate" do
31
+ ::RiCal::PropertyValue::DateTime.default_tzid = 'UTC'
32
32
  @event.rdate = Time.local(2009, 1, 2, 1, 23, 45)
33
- @event.rdate.should == [[DateTime.parse("20090102T012345")]]
33
+ @event.rdate.should == [[result_time_in_zone(2009, 1, 2, 1, 23, 45, "UTC")]]
34
34
  end
35
35
 
36
36
  it "should accept a single rfc2445 date-time format string and replace the existing rdate" do
@@ -40,7 +40,7 @@ describe RiCal::Component::Event do
40
40
 
41
41
  it "should accept a tzid prefixed rfc2445 date-time format string and replace the existing rdate" do
42
42
  @event.rdate = "TZID=America/New_York:20090102T012345"
43
- @event.rdate.should == [[DateTime.civil(2009, 1, 2, 1, 23, 45, Rational(-5, 24))]]
43
+ @event.rdate.should == [[result_time_in_zone(2009, 1, 2, 1, 23, 45, "America/New_York")]]
44
44
  end
45
45
 
46
46
  end
@@ -129,7 +129,7 @@ describe RiCal::Component::Event do
129
129
  end
130
130
 
131
131
  it "should interpret it as the correct date-time" do
132
- @it.should == DateTime.civil(2009, 5, 14, 20, 24, 00, Rational(-5,24))
132
+ @it.should == result_time_in_zone(2009, 5, 14, 20, 24, 00, "America/New_York")
133
133
  end
134
134
 
135
135
  it "should set the tzid to America/New_York" do
@@ -309,4 +309,115 @@ describe RiCal::Component::Event do
309
309
  unfold(@it.export).should match(/^DTSTART;VALUE=DATE:20090422$/)
310
310
  end
311
311
  end
312
+
313
+ if RiCal::TimeWithZone
314
+ context "with ActiveSupport loaded" do
315
+
316
+ context "An event in a non-tzinfo source calendar" do
317
+ before(:each) do
318
+ cals = RiCal.parse_string <<ENDCAL
319
+ BEGIN:VCALENDAR
320
+ X-WR-TIMEZONE:America/New_York
321
+ PRODID:-//Apple Inc.//iCal 3.0//EN
322
+ CALSCALE:GREGORIAN
323
+ BEGIN:VTIMEZONE
324
+ TZID:US/Eastern
325
+ BEGIN:DAYLIGHT
326
+ TZOFFSETFROM:-0500
327
+ TZOFFSETTO:-0400
328
+ DTSTART:20070311T020000
329
+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
330
+ TZNAME:EDT
331
+ END:DAYLIGHT
332
+ BEGIN:STANDARD
333
+ TZOFFSETFROM:-0400
334
+ TZOFFSETTO:-0500
335
+ DTSTART:20071104T020000
336
+ RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
337
+ TZNAME:EST
338
+ END:STANDARD
339
+ END:VTIMEZONE
340
+ BEGIN:VEVENT
341
+ SEQUENCE:5
342
+ TRANSP:OPAQUE
343
+ UID:00481E53-9258-4EA7-9F8D-947D3041A3F2
344
+ DTSTART;TZID=US/Eastern:20090224T090000
345
+ DTSTAMP:20090225T000908Z
346
+ SUMMARY:Test Event
347
+ CREATED:20090225T000839Z
348
+ DTEND;TZID=US/Eastern:20090224T100000
349
+ RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20090228T045959Z
350
+ END:VEVENT
351
+ END:VCALENDAR
352
+ ENDCAL
353
+ @event = cals.first.events.first
354
+ end
355
+
356
+ it "should produce a DateTime for dtstart" do
357
+ @event.dtstart.should be_instance_of(DateTime)
358
+ end
359
+ end
360
+
361
+ context "An event starting in Paris and ending in New York" do
362
+
363
+ before(:each) do
364
+ @start = Time.now.utc.in_time_zone("Europe/Paris")
365
+ @finish = Time.now.utc.in_time_zone("America/New_York")
366
+ cal = RiCal.Calendar do |ical|
367
+ ical.event do |ievent|
368
+ ievent.dtstart @start
369
+ ievent.dtend @finish
370
+ end
371
+ end
372
+ @event = cal.events.first
373
+ end
374
+
375
+ it "should have the right time zone for dtstart" do
376
+ @event.dtstart.tzid.should == "Europe/Paris"
377
+ end
378
+
379
+ it "should produce a TimeWithZone for dtstart" do
380
+ @event.dtstart.should be_instance_of(RiCal::TimeWithZone)
381
+ end
382
+
383
+ # ActiveRecord::TimeWithZone doesn't implement == as expected
384
+ it "should produce a dtstart which looks like the provided value" do
385
+ @event.dtstart.to_s.should == @start.to_s
386
+ end
387
+
388
+ it "should have the right time zone for dtend" do
389
+ @event.dtend.tzid.should == "America/New_York"
390
+ end
391
+
392
+ it "should produce a TimeWithZone for dtend" do
393
+ @event.dtend.should be_instance_of(RiCal::TimeWithZone)
394
+ end
395
+
396
+ # ActiveRecord::TimeWithZone doesn't implement == as expected
397
+ it "should produce a dtend which looks like the provided value" do
398
+ @event.dtend.to_s.should == @finish.to_s
399
+ end
400
+ end
401
+ end
402
+ end
403
+
404
+ context "An event with a floating start" do
405
+
406
+ before(:each) do
407
+ cal = RiCal.Calendar do |ical|
408
+ ical.event do |ievent|
409
+ ievent.dtstart "20090530T120000"
410
+ end
411
+ end
412
+ @event = cal.events.first
413
+ end
414
+
415
+ it "should produce a DateTime for dtstart" do
416
+ @event.dtstart.should be_instance_of(DateTime)
417
+ end
418
+
419
+ it "should have a floating dtstart" do
420
+ @event.dtstart.should have_floating_timezone
421
+ end
422
+ end
312
423
  end
@@ -197,7 +197,7 @@ ENDCAL
197
197
 
198
198
  context "the events dtstart" do
199
199
  it "should be the right DateTime" do
200
- @event.dtstart.should == DateTime.civil(2009, 2, 24, 9, 0, 0, Rational(-4, 24))
200
+ @event.dtstart.should == DateTime.civil(2009, 2, 24, 9, 0, 0, Rational(-5, 24))
201
201
  end
202
202
 
203
203
  it "should have the right tzid" do
@@ -207,7 +207,7 @@ ENDCAL
207
207
 
208
208
  context "the events dtend" do
209
209
  it "should be the right DateTime" do
210
- @event.dtend.should == DateTime.civil(2009, 2, 24, 10, 0, 0, Rational(-4, 24))
210
+ @event.dtend.should == DateTime.civil(2009, 2, 24, 10, 0, 0, Rational(-5, 24))
211
211
  end
212
212
 
213
213
  it "should have the right tzid" do
@@ -3,65 +3,70 @@
3
3
  require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
4
4
 
5
5
  describe RiCal::PropertyValue::OccurrenceList do
6
-
6
+
7
7
  context ".convert method" do
8
8
  context "with a single datetime" do
9
9
  before(:each) do
10
10
  @it = RiCal::PropertyValue::OccurrenceList.convert(nil, DateTime.parse("5 May 2009, 9:32 am"))
11
11
  end
12
-
12
+
13
13
  it "should produce the right ical representation" do
14
14
  @it.to_s.should == ":20090505T093200Z"
15
15
  end
16
-
16
+
17
17
  it "should have the right ruby value" do
18
18
  @it.ruby_value.should == [DateTime.parse("5 May 2009, 9:32 am")]
19
19
  end
20
-
20
+
21
21
  it "should have the right elements" do
22
22
  @it.send(:elements).should == [RiCal::PropertyValue::DateTime.new(nil, :value => "20090505T093200Z" )]
23
23
  end
24
24
  end
25
-
25
+
26
26
  context "with conflicting timezones" do
27
27
  before(:each) do
28
28
  @event = RiCal.Event
29
29
  end
30
-
30
+
31
31
  it "should raise an InvalidPropertyValue if an argument does not match an explicit time zone" do
32
32
  lambda {RiCal::PropertyValue::OccurrenceList.convert(@event, "America/New_York", Time.now.set_tzid("America/Chicago"))}.should raise_error(RiCal::InvalidPropertyValue)
33
33
  end
34
-
34
+
35
35
  it "should raise an InvalidPropertyValue if the arguments have mixed time zones" do
36
36
  lambda {RiCal::PropertyValue::OccurrenceList.convert(@event, Time.now.set_tzid("America/New_York"), Time.now.set_tzid("America/Chicago"))}.should raise_error(RiCal::InvalidPropertyValue)
37
37
  end
38
38
  end
39
-
39
+
40
40
  context "with a tzid and a single datetime" do
41
41
  before(:each) do
42
- timezone = mock("Timezone", :rational_utc_offset => Rational(-5, 24))
43
- timezone_finder = mock("tz_finder", :find_timezone => timezone, :default_tzid => "UTC")
44
- @it = RiCal::PropertyValue::OccurrenceList.convert(timezone_finder, 'US/Eastern', "19620220T144739")
42
+ timezone = mock("Timezone",
43
+ :rational_utc_offset => Rational(-5, 24),
44
+ :local_to_utc => RiCal::PropertyValue.date_or_date_time(nil, :value => "19620220T194739"),
45
+ :name => 'America/New_York'
46
+ )
47
+
48
+ timezone_finder = mock("tz_finder", :find_timezone => timezone, :default_tzid => "UTC", :tz_info_source? => true)
49
+ @it = RiCal::PropertyValue::OccurrenceList.convert(timezone_finder, 'America/New_York', "19620220T144739")
45
50
  end
46
-
51
+
47
52
  it "should produce the right ical representation" do
48
- @it.to_s.should == ";TZID=US/Eastern:19620220T144739"
53
+ @it.to_s.should == ";TZID=America/New_York:19620220T144739"
49
54
  end
50
-
55
+
51
56
  context "its ruby value" do
52
57
 
53
58
  it "should be the right DateTime" do
54
- @it.ruby_value.should == [DateTime.civil(1962, 2, 20, 14, 47, 39, Rational(-5, 24))]
59
+ @it.ruby_value.should == [result_time_in_zone(1962, 2, 20, 14, 47, 39, 'America/New_York')]
55
60
  end
56
-
61
+
57
62
  it "should have the right tzid" do
58
- @it.ruby_value.first.tzid.should == "US/Eastern"
63
+ @it.ruby_value.first.tzid.should == "America/New_York"
59
64
  end
60
65
  end
61
-
66
+
62
67
  it "should have the right elements" do
63
- @it.send(:elements).should == [RiCal::PropertyValue::DateTime.new(nil, :params=> {'TZID' => 'US/Eastern'}, :value => "19620220T144739" )]
68
+ @it.send(:elements).should == [RiCal::PropertyValue::DateTime.new(nil, :params=> {'TZID' => 'America/New_York'}, :value => "19620220T144739" )]
64
69
  end
65
70
  end
66
- end
71
+ end
67
72
  end
@@ -1,5 +1,4 @@
1
1
  #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
2
-
3
2
  require File.join(File.dirname(__FILE__), %w[.. spec_helper])
4
3
  require 'tzinfo'
5
4
 
@@ -81,7 +80,11 @@ describe RiCal::PropertyValue do
81
80
 
82
81
  describe "FORM #3 date with local time and time zone reference p 36" do
83
82
  before(:each) do
84
- timezone = mock("Timezone", :rational_utc_offset => Rational(-4, 24))
83
+ timezone = mock("Timezone",
84
+ :rational_utc_offset => Rational(-4, 24),
85
+ :local_to_utc => RiCal::PropertyValue.date_or_date_time(nil, :value => "19970714T163456Z"),
86
+ :name => 'US-Eastern'
87
+ )
85
88
  timezone_finder = mock("tz_finder", :find_timezone => timezone)
86
89
  @prop = RiCal::PropertyValue.date_or_date_time(timezone_finder, :value => "19970714T123456", :params => {'TZID' => 'US-Eastern'})
87
90
  end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib ri_cal]))
4
4
  require 'cgi'
5
+ require 'tzinfo'
5
6
 
6
7
  module Kernel
7
8
  def rputs(*args)
@@ -17,3 +18,25 @@ end
17
18
  def dt_prop(date_time, tzid = "US/Eastern")
18
19
  RiCal::PropertyValue::DateTime.convert(nil, date_time_with_zone(date_time, tzid))
19
20
  end
21
+
22
+ def offset_for_tzid(year, month, day, hour, min, sec, tzid, alternate)
23
+ tz = TZInfo::Timezone.get(tzid) rescue nil
24
+ if tz
25
+ Rational(tz.period_for_local(DateTime.civil(year, month, day, hour, min, sec)).utc_total_offset, 86400)
26
+ else
27
+ provided_offset
28
+ end
29
+ end
30
+
31
+ if RiCal::TimeWithZone
32
+ def result_time_in_zone(year, month, day, hour, min, sec, tzid, alternate_offset = nil)
33
+ DateTime.civil(year, month, day, hour, min, sec,
34
+ offset_for_tzid(year, month, day, hour, min, sec, tzid, alternate_offset)).in_time_zone(tzid)
35
+ end
36
+ else
37
+ def result_time_in_zone(year, month, day, hour, min, sec, tzid, alternate_offset = nil)
38
+ DateTime.civil(year, month, day, hour, min, sec,
39
+ offset_for_tzid(year, month, day, hour, min, sec, tzid, alternate_offset)).set_tzid(tzid)
40
+ end
41
+ end
42
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyredrick-ri_cal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - author=Rick DeNatale
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-17 00:00:00 -07:00
12
+ date: 2009-05-18 00:00:00 -07:00
13
13
  default_executable: ri_cal
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency