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 +6 -2
- data/README.txt +37 -0
- data/lib/ri_cal/component/calendar.rb +10 -6
- data/lib/ri_cal/component/timezone/daylight_period.rb +1 -1
- data/lib/ri_cal/component/timezone/timezone_period.rb +1 -1
- data/lib/ri_cal/component.rb +17 -9
- data/lib/ri_cal/core_extensions/time/tzid_access.rb +18 -7
- data/lib/ri_cal/property_value/date_time/timezone_support.rb +14 -1
- data/lib/ri_cal/property_value/date_time.rb +6 -6
- data/lib/ri_cal/property_value/occurrence_list.rb +1 -1
- data/lib/ri_cal/property_value.rb +8 -0
- data/lib/ri_cal.rb +12 -1
- data/ri_cal.gemspec +2 -2
- data/spec/ri_cal/component/event_spec.rb +115 -4
- data/spec/ri_cal/component/timezone_spec.rb +2 -2
- data/spec/ri_cal/property_value/occurrence_list_spec.rb +25 -20
- data/spec/ri_cal/property_value_spec.rb +5 -2
- data/spec/spec_helper.rb +23 -0
- metadata +2 -2
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
|
-
|
5
|
-
|
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
|
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
|
-
|
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
|
-
|
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).
|
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 -
|
20
|
+
local.advance(:seconds => (std_candidate.utc_total_offset - utc_total_offset)) < dtstart_property
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/ri_cal/component.rb
CHANGED
@@ -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.
|
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
|
32
|
-
|
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
|
-
|
284
|
-
|
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
|
-
|
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)
|
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.
|
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.
|
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-
|
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 == [[
|
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 == [[
|
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 ==
|
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(-
|
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(-
|
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",
|
43
|
-
|
44
|
-
|
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=
|
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 == [
|
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 == "
|
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' => '
|
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",
|
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.
|
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-
|
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
|