rubyredrick-ri_cal 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|