demingfactor-ri_cal 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/History.txt +402 -0
- data/Manifest.txt +161 -0
- data/README.txt +410 -0
- data/Rakefile +69 -0
- data/VERSION +1 -0
- data/bin/ri_cal +8 -0
- data/component_attributes/alarm.yml +10 -0
- data/component_attributes/calendar.yml +4 -0
- data/component_attributes/component_property_defs.yml +180 -0
- data/component_attributes/event.yml +45 -0
- data/component_attributes/freebusy.yml +16 -0
- data/component_attributes/journal.yml +35 -0
- data/component_attributes/timezone.yml +3 -0
- data/component_attributes/timezone_period.yml +11 -0
- data/component_attributes/todo.yml +46 -0
- data/copyrights.txt +1 -0
- data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
- data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
- data/docs/incrementers.txt +7 -0
- data/docs/rfc2445.pdf +0 -0
- data/lib/ri_cal/component/alarm.rb +19 -0
- data/lib/ri_cal/component/calendar.rb +257 -0
- data/lib/ri_cal/component/event.rb +58 -0
- data/lib/ri_cal/component/freebusy.rb +16 -0
- data/lib/ri_cal/component/journal.rb +27 -0
- data/lib/ri_cal/component/non_standard.rb +33 -0
- data/lib/ri_cal/component/t_z_info_timezone.rb +153 -0
- data/lib/ri_cal/component/timezone/daylight_period.rb +25 -0
- data/lib/ri_cal/component/timezone/standard_period.rb +23 -0
- data/lib/ri_cal/component/timezone/timezone_period.rb +76 -0
- data/lib/ri_cal/component/timezone.rb +197 -0
- data/lib/ri_cal/component/todo.rb +42 -0
- data/lib/ri_cal/component.rb +256 -0
- data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
- data/lib/ri_cal/core_extensions/array.rb +7 -0
- data/lib/ri_cal/core_extensions/date/conversions.rb +56 -0
- data/lib/ri_cal/core_extensions/date.rb +13 -0
- data/lib/ri_cal/core_extensions/date_time/conversions.rb +50 -0
- data/lib/ri_cal/core_extensions/date_time.rb +15 -0
- data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
- data/lib/ri_cal/core_extensions/object.rb +8 -0
- data/lib/ri_cal/core_extensions/string/conversions.rb +57 -0
- data/lib/ri_cal/core_extensions/string.rb +8 -0
- data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
- data/lib/ri_cal/core_extensions/time/conversions.rb +42 -0
- data/lib/ri_cal/core_extensions/time/tzid_access.rb +50 -0
- data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +55 -0
- data/lib/ri_cal/core_extensions/time.rb +14 -0
- data/lib/ri_cal/core_extensions.rb +11 -0
- data/lib/ri_cal/fast_date_time.rb +234 -0
- data/lib/ri_cal/floating_timezone.rb +32 -0
- data/lib/ri_cal/invalid_property_value.rb +8 -0
- data/lib/ri_cal/invalid_timezone_identifier.rb +20 -0
- data/lib/ri_cal/occurrence_enumerator.rb +265 -0
- data/lib/ri_cal/occurrence_period.rb +17 -0
- data/lib/ri_cal/parser.rb +148 -0
- data/lib/ri_cal/properties/alarm.rb +390 -0
- data/lib/ri_cal/properties/calendar.rb +164 -0
- data/lib/ri_cal/properties/event.rb +1523 -0
- data/lib/ri_cal/properties/freebusy.rb +593 -0
- data/lib/ri_cal/properties/journal.rb +1237 -0
- data/lib/ri_cal/properties/timezone.rb +150 -0
- data/lib/ri_cal/properties/timezone_period.rb +416 -0
- data/lib/ri_cal/properties/todo.rb +1559 -0
- data/lib/ri_cal/properties.rb +12 -0
- data/lib/ri_cal/property_value/array.rb +27 -0
- data/lib/ri_cal/property_value/cal_address.rb +11 -0
- data/lib/ri_cal/property_value/date.rb +184 -0
- data/lib/ri_cal/property_value/date_time/additive_methods.rb +44 -0
- data/lib/ri_cal/property_value/date_time/time_machine.rb +159 -0
- data/lib/ri_cal/property_value/date_time/timezone_support.rb +100 -0
- data/lib/ri_cal/property_value/date_time.rb +359 -0
- data/lib/ri_cal/property_value/duration.rb +110 -0
- data/lib/ri_cal/property_value/geo.rb +11 -0
- data/lib/ri_cal/property_value/integer.rb +12 -0
- data/lib/ri_cal/property_value/occurrence_list.rb +144 -0
- data/lib/ri_cal/property_value/period.rb +86 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +100 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +79 -0
- data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +148 -0
- data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +53 -0
- data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +31 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +86 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +38 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +69 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +80 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +106 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +43 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +135 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +131 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +64 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +33 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +53 -0
- data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
- data/lib/ri_cal/property_value/recurrence_rule/validations.rb +125 -0
- data/lib/ri_cal/property_value/recurrence_rule.rb +154 -0
- data/lib/ri_cal/property_value/text.rb +44 -0
- data/lib/ri_cal/property_value/uri.rb +11 -0
- data/lib/ri_cal/property_value/utc_offset.rb +33 -0
- data/lib/ri_cal/property_value/zulu_date_time.rb +34 -0
- data/lib/ri_cal/property_value.rb +159 -0
- data/lib/ri_cal/required_timezones.rb +55 -0
- data/lib/ri_cal.rb +187 -0
- data/parked_specs/ri_cal/claudio_a_bug_spec.rb +100 -0
- data/performance/empty_propval/subject.rb +43 -0
- data/performance/paris_eastern/subject.rb +90 -0
- data/performance/penultimate_weekday/subject.rb +15 -0
- data/performance/psm_big_enum/ical.ics +3171 -0
- data/performance/psm_big_enum/subject.rb +16 -0
- data/performance/utah_cycling/subject.rb +55 -0
- data/ri_cal.gemspec +244 -0
- data/script/benchmark_subject +23 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/profile_subject +29 -0
- data/script/txt2html +71 -0
- data/spec/ri_cal/bugreports_spec.rb +276 -0
- data/spec/ri_cal/component/alarm_spec.rb +12 -0
- data/spec/ri_cal/component/calendar_spec.rb +88 -0
- data/spec/ri_cal/component/event_spec.rb +735 -0
- data/spec/ri_cal/component/freebusy_spec.rb +12 -0
- data/spec/ri_cal/component/journal_spec.rb +37 -0
- data/spec/ri_cal/component/t_z_info_timezone_spec.rb +60 -0
- data/spec/ri_cal/component/timezone_spec.rb +236 -0
- data/spec/ri_cal/component/todo_spec.rb +112 -0
- data/spec/ri_cal/component_spec.rb +224 -0
- data/spec/ri_cal/core_extensions/string/conversions_spec.rb +78 -0
- data/spec/ri_cal/core_extensions/time/calculations_spec.rb +188 -0
- data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +45 -0
- data/spec/ri_cal/fast_date_time_spec.rb +77 -0
- data/spec/ri_cal/inf_loop_spec.rb +78 -0
- data/spec/ri_cal/occurrence_enumerator_spec.rb +611 -0
- data/spec/ri_cal/parser_spec.rb +337 -0
- data/spec/ri_cal/property_value/date_spec.rb +53 -0
- data/spec/ri_cal/property_value/date_time_spec.rb +383 -0
- data/spec/ri_cal/property_value/duration_spec.rb +126 -0
- data/spec/ri_cal/property_value/occurrence_list_spec.rb +72 -0
- data/spec/ri_cal/property_value/period_spec.rb +63 -0
- data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +21 -0
- data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1814 -0
- data/spec/ri_cal/property_value/text_spec.rb +25 -0
- data/spec/ri_cal/property_value/utc_offset_spec.rb +48 -0
- data/spec/ri_cal/property_value_spec.rb +125 -0
- data/spec/ri_cal/required_timezones_spec.rb +67 -0
- data/spec/ri_cal_spec.rb +53 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +50 -0
- data/tasks/gem_loader/load_active_support.rb +3 -0
- data/tasks/gem_loader/load_tzinfo_gem.rb +2 -0
- data/tasks/ri_cal.rake +412 -0
- data/tasks/spec.rake +102 -0
- metadata +246 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
module RiCal
|
2
|
+
module Properties #:nodoc:
|
3
|
+
autoload :Alarm, "ri_cal/properties/alarm.rb"
|
4
|
+
autoload :Calendar, "ri_cal/properties/calendar.rb"
|
5
|
+
autoload :Event, "ri_cal/properties/event.rb"
|
6
|
+
autoload :Freebusy, "ri_cal/properties/freebusy.rb"
|
7
|
+
autoload :Journal, "ri_cal/properties/journal.rb"
|
8
|
+
autoload :Timezone, "ri_cal/properties/timezone.rb"
|
9
|
+
autoload :TimezonePeriod, "ri_cal/properties/timezone_period.rb"
|
10
|
+
autoload :Todo, "ri_cal/properties/todo.rb"
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
4
|
+
#
|
5
|
+
class Array < PropertyValue # :nodoc:
|
6
|
+
|
7
|
+
def value=(val)
|
8
|
+
case val
|
9
|
+
when String
|
10
|
+
@value = val.split(",")
|
11
|
+
else
|
12
|
+
@value = val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def value
|
17
|
+
@value.join(",")
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.convert(timezone_finder, ruby_object) # :nodoc:
|
21
|
+
self.new(timezone_finder, :value => ruby_object)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
4
|
+
#
|
5
|
+
# RiCal::PropertyValue::CalAddress represents an icalendar CalAddress property value
|
6
|
+
# which is defined in
|
7
|
+
# RFC 2445 section 4.3.3 p 34
|
8
|
+
class CalAddress < PropertyValue
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'date'
|
2
|
+
module RiCal
|
3
|
+
class PropertyValue
|
4
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# RiCal::PropertyValue::CalAddress represents an icalendar Date property value
|
7
|
+
# which is defined in
|
8
|
+
# RFC 2445 section 4.3.4 p 34
|
9
|
+
class Date < PropertyValue
|
10
|
+
|
11
|
+
def self.valid_string?(string) #:nodoc:
|
12
|
+
string =~ /^\d{8}$/
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the value of the reciever as an RFC 2445 iCalendar string
|
16
|
+
def value
|
17
|
+
if @date_time_value
|
18
|
+
@date_time_value.ical_date_str
|
19
|
+
else
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_ri_cal_zulu_date_time
|
25
|
+
self.to_ri_cal_date_time_value.to_ri_cal_zulu_date_time
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set the value of the property to val
|
29
|
+
#
|
30
|
+
# val may be either:
|
31
|
+
#
|
32
|
+
# * A string which can be parsed as a DateTime
|
33
|
+
# * A Time instance
|
34
|
+
# * A Date instance
|
35
|
+
# * A DateTime instance
|
36
|
+
def value=(val)
|
37
|
+
case val
|
38
|
+
when nil
|
39
|
+
@date_time_value = nil
|
40
|
+
when String
|
41
|
+
@date_time_value = FastDateTime.from_date_time(::DateTime.parse(::DateTime.parse(val).strftime("%Y%m%d")))
|
42
|
+
when ::Time, ::Date, ::DateTime
|
43
|
+
@date_time_value = FastDateTime.from_date_time(::DateTime.parse(val.strftime("%Y%m%d")))
|
44
|
+
when FastDateTime
|
45
|
+
@date_time_value = val
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Nop to allow occurrence list to try to set it
|
50
|
+
def tzid=(val)#:nodoc:
|
51
|
+
end
|
52
|
+
|
53
|
+
def tzid #:nodoc:
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def visible_params #:nodoc:
|
58
|
+
{"VALUE" => "DATE"}.merge(params)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the year (including the century)
|
62
|
+
def year
|
63
|
+
@date_time_value.year
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the month of the year (1..12)
|
67
|
+
def month
|
68
|
+
@date_time_value.month
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the day of the month
|
72
|
+
def day
|
73
|
+
@date_time_value.day
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the ruby representation a ::Date
|
77
|
+
def ruby_value
|
78
|
+
@date_time_value.date
|
79
|
+
end
|
80
|
+
|
81
|
+
alias_method :to_ri_cal_ruby_value, :ruby_value
|
82
|
+
|
83
|
+
# Return an instance of RiCal::PropertyValue::DateTime representing the start of this date
|
84
|
+
def to_ri_cal_date_time_value
|
85
|
+
PropertyValue::DateTime.new(timezone_finder, :value => @date_time_value)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return this date property
|
89
|
+
def to_ri_cal_date_value(timezone_finder = nil)
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
# Return the "Natural' property value for the date_property, in this case the date property itself."
|
94
|
+
def to_ri_cal_date_or_date_time_value
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def for_parent(parent) #:nodoc:
|
99
|
+
if timezone_finder.nil?
|
100
|
+
@timezone_finder = parent
|
101
|
+
self
|
102
|
+
elsif parent == timezone_finder
|
103
|
+
self
|
104
|
+
else
|
105
|
+
Date.new(parent, :value => @date_time_value)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def advance(options) #:nodoc:
|
110
|
+
PropertyValue::Date.new(timezone_finder, :value => @date_time_value.advance(options), :params =>(params ? params.dup : nil) )
|
111
|
+
end
|
112
|
+
|
113
|
+
def change(options) #:nodoc:
|
114
|
+
PropertyValue::Date.new(timezone_finder,:value => @date_time_value.change(options), :params => (params ? params.dup : nil) )
|
115
|
+
end
|
116
|
+
|
117
|
+
def add_date_times_to(required_timezones) #:nodoc:
|
118
|
+
# Do nothing since dates don't have a timezone
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return the difference between the receiver and other
|
122
|
+
#
|
123
|
+
# The parameter other should be either a RiCal::PropertyValue::Duration or a RiCal::PropertyValue::DateTime
|
124
|
+
#
|
125
|
+
# If other is a Duration, the result will be a DateTime, if it is a DateTime the result will be a Duration
|
126
|
+
def -(other)
|
127
|
+
other.subtract_from_date_time_value(to_ri_cal_date_time_value)
|
128
|
+
end
|
129
|
+
|
130
|
+
def subtract_from_date_time_value(date_time)
|
131
|
+
to_ri_cal_date_time_value.subtract_from_date_time_value(date_time)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Return the sum of the receiver and duration
|
135
|
+
#
|
136
|
+
# The parameter other duration should be a RiCal::PropertyValue::Duration
|
137
|
+
#
|
138
|
+
# The result will be an RiCal::PropertyValue::DateTime
|
139
|
+
def +(duration)
|
140
|
+
duration.add_to_date_time_value(to_ri_cal_date_time_value)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Delegate unknown messages to the wrappered Date instance.
|
144
|
+
# TODO: Is this really necessary?
|
145
|
+
def method_missing(selector, *args) #:nodoc:
|
146
|
+
@date_time_value.send(selector, *args)
|
147
|
+
end
|
148
|
+
|
149
|
+
# TODO: consider if this should be a period rather than a hash
|
150
|
+
def occurrence_period(default_duration) #:nodoc:
|
151
|
+
date_time = self.to_ri_cal_date_time_value
|
152
|
+
RiCal::OccurrencePeriod.new(date_time, date_time.advance(:hours => 24, :seconds => -1))
|
153
|
+
end
|
154
|
+
|
155
|
+
def start_of_day?
|
156
|
+
true
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_floating_date_time_property
|
160
|
+
PropertyValue::DateTime.new(timezone_finder, :value => @date_time_value.ical_str)
|
161
|
+
end
|
162
|
+
|
163
|
+
def to_zulu_occurrence_range_start_time
|
164
|
+
to_floating_date_time_property.to_zulu_occurrence_range_start_time
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_zulu_occurrence_range_finish_time
|
168
|
+
to_ri_cal_date_time_value.end_of_day.to_zulu_occurrence_range_finish_time
|
169
|
+
end
|
170
|
+
|
171
|
+
def to_finish_time
|
172
|
+
to_ri_cal_date_time_value.end_of_day.to_datetime
|
173
|
+
end
|
174
|
+
|
175
|
+
def for_occurrence(occurrence)
|
176
|
+
if occurrence.start_of_day?
|
177
|
+
occurrence.to_ri_cal_date_value(timezone_finder)
|
178
|
+
else
|
179
|
+
occurrence.for_parent(timezone_finder)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
class DateTime
|
4
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# Methods for DateTime which support adding or subtracting another DateTime or Duration
|
7
|
+
module AdditiveMethods
|
8
|
+
# if end_time is nil => nil
|
9
|
+
# otherwise convert end_time to a DateTime and compute the difference
|
10
|
+
def duration_until(end_time) # :nodoc:
|
11
|
+
end_time && RiCal::PropertyValue::Duration.from_datetimes(timezone_finder, to_datetime, end_time.to_datetime)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Double-dispatch method for subtraction.
|
15
|
+
def subtract_from_date_time_value(dtvalue) #:nodoc:
|
16
|
+
RiCal::PropertyValue::Duration.from_datetimes(timezone_finder, to_datetime,dtvalue.to_datetime)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Double-dispatch method for addition.
|
20
|
+
def add_to_date_time_value(date_time_value) #:nodoc:
|
21
|
+
raise ArgumentError.new("Cannot add #{date_time_value} to #{self}")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return the difference between the receiver and other
|
25
|
+
#
|
26
|
+
# The parameter other should be either a RiCal::PropertyValue::Duration or a RiCal::PropertyValue::DateTime
|
27
|
+
#
|
28
|
+
# If other is a Duration, the result will be a DateTime, if it is a DateTime the result will be a Duration
|
29
|
+
def -(other)
|
30
|
+
other.subtract_from_date_time_value(self)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return the sum of the receiver and duration
|
34
|
+
#
|
35
|
+
# The parameter other duration should be a RiCal::PropertyValue::Duration
|
36
|
+
#
|
37
|
+
# The result will be an RiCal::PropertyValue::DateTime
|
38
|
+
def +(duration)
|
39
|
+
duration.add_to_date_time_value(self)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
class DateTime
|
4
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# Methods for DateTime which support getting values at different point in time.
|
7
|
+
module TimeMachine
|
8
|
+
|
9
|
+
def advance(options) # :nodoc:
|
10
|
+
PropertyValue::DateTime.new(timezone_finder,
|
11
|
+
:value => @date_time_value.advance(options),
|
12
|
+
:tzid => @tzid,
|
13
|
+
:params =>(params ? params.dup : nil)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def change(options) # :nodoc:
|
18
|
+
PropertyValue::DateTime.new(timezone_finder,
|
19
|
+
:value => @date_time_value.change(options),
|
20
|
+
:tzid => @tzid,
|
21
|
+
:params => (params ? params.dup : nil)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def change_sec(new_sec) #:nodoc:
|
26
|
+
change(:sec => new_sec)
|
27
|
+
end
|
28
|
+
|
29
|
+
def change_min(new_min) #:nodoc:
|
30
|
+
change(:min => new_min)
|
31
|
+
end
|
32
|
+
|
33
|
+
def change_hour(new_hour) #:nodoc:
|
34
|
+
change(:hour => new_hour)
|
35
|
+
end
|
36
|
+
|
37
|
+
def change_day(new_day) #:nodoc:
|
38
|
+
change(:day => new_day)
|
39
|
+
end
|
40
|
+
|
41
|
+
def change_month(new_month) #:nodoc:
|
42
|
+
change(:month => new_month)
|
43
|
+
end
|
44
|
+
|
45
|
+
def change_year(new_year) #:nodoc:
|
46
|
+
change(:year => new_year)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a DATE-TIME property representing the receiver on a different day (if necessary) so that
|
50
|
+
# the result is within the 7 days starting with date
|
51
|
+
def in_week_starting?(date)
|
52
|
+
wkst_jd = date.jd
|
53
|
+
@date_time_value.jd.between?(wkst_jd, wkst_jd + 6)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return a DATE-TIME property representing the receiver on a different day (if necessary) so that
|
57
|
+
# the result is the first day of the ISO week starting on the wkst day containing the receiver.
|
58
|
+
def at_start_of_week_with_wkst(wkst)
|
59
|
+
date = @date_time_value.start_of_week_with_wkst(wkst)
|
60
|
+
change(:year => date.year, :month => date.month, :day => date.day)
|
61
|
+
end
|
62
|
+
# Return a DATE_TIME value representing the first second of the minute containing the receiver
|
63
|
+
def start_of_minute
|
64
|
+
change(:sec => 0)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return a DATE_TIME value representing the last second of the minute containing the receiver
|
68
|
+
def end_of_minute
|
69
|
+
change(:sec => 59)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return a DATE_TIME value representing the first second of the hour containing the receiver
|
73
|
+
def start_of_hour
|
74
|
+
change(:min => 0, :sec => 0)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return a DATE_TIME value representing the last second of the hour containing the receiver
|
78
|
+
def end_of_hour
|
79
|
+
change(:min => 59, :sec => 59)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return a DATE_TIME value representing the first second of the day containing the receiver
|
83
|
+
def start_of_day
|
84
|
+
change(:hour => 0, :min => 0, :sec => 0)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return a DATE_TIME value representing the last second of the day containing the receiver
|
88
|
+
def end_of_day
|
89
|
+
change(:hour => 23, :min => 59, :sec => 59)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return a Ruby Date representing the first day of the ISO week starting with wkst containing the receiver
|
93
|
+
def start_of_week_with_wkst(wkst)
|
94
|
+
@date_time_value.start_of_week_with_wkst(wkst)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return a DATE_TIME value representing the last second of the ISO week starting with wkst containing the receiver
|
98
|
+
def end_of_week_with_wkst(wkst)
|
99
|
+
date = at_start_of_week_with_wkst(wkst).advance(:days => 6).end_of_day
|
100
|
+
end
|
101
|
+
|
102
|
+
# Return a DATE_TIME value representing the first second of the month containing the receiver
|
103
|
+
def start_of_month
|
104
|
+
change(:day => 1, :hour => 0, :min => 0, :sec => 0)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return a DATE_TIME value representing the last second of the month containing the receiver
|
108
|
+
def end_of_month
|
109
|
+
change(:day => days_in_month, :hour => 23, :min => 59, :sec => 59)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return a DATE_TIME value representing the first second of the month containing the receiver
|
113
|
+
def start_of_year
|
114
|
+
change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Return a DATE_TIME value representing the last second of the month containing the receiver
|
118
|
+
def end_of_year
|
119
|
+
change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Return a DATE_TIME value representing the same time on the first day of the ISO year with weeks
|
123
|
+
# starting on wkst containing the receiver
|
124
|
+
def at_start_of_iso_year(wkst)
|
125
|
+
start_of_year = @date_time_value.iso_year_start(wkst)
|
126
|
+
change(:year => start_of_year.year, :month => start_of_year.month, :day => start_of_year.day)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Return a DATE_TIME value representing the same time on the last day of the ISO year with weeks
|
130
|
+
# starting on wkst containing the receiver
|
131
|
+
def at_end_of_iso_year(wkst)
|
132
|
+
num_weeks = @date_time_value.iso_weeks_in_year(wkst)
|
133
|
+
at_start_of_iso_year(wkst).advance(:weeks => (num_weeks - 1), :days => 6)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Return a DATE_TIME value representing the same time on the first day of the ISO year with weeks
|
137
|
+
# starting on wkst after the ISO year containing the receiver
|
138
|
+
def at_start_of_next_iso_year(wkst)
|
139
|
+
num_weeks = @date_time_value.iso_weeks_in_year(wkst)
|
140
|
+
at_start_of_iso_year(wkst).advance(:weeks => num_weeks)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Return a DATE_TIME value representing the last second of the last day of the ISO year with weeks
|
144
|
+
# starting on wkst containing the receiver
|
145
|
+
def end_of_iso_year(wkst)
|
146
|
+
at_end_of_iso_year(wkst).end_of_day
|
147
|
+
end
|
148
|
+
|
149
|
+
# Return a DATE-TIME representing the same time, on the same day of the month in month.
|
150
|
+
# If the month of the receiver has more days than the target month the last day of the target month
|
151
|
+
# will be used.
|
152
|
+
def in_month(month)
|
153
|
+
first = change(:day => 1, :month => month)
|
154
|
+
first.change(:day => [first.days_in_month, day].min)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
class DateTime
|
4
|
+
#- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# Time zone related methods for DateTime
|
7
|
+
module TimezoneSupport
|
8
|
+
# Return the timezone id of the receiver, or nil if it is a floating time
|
9
|
+
def tzid
|
10
|
+
@tzid == :floating ? nil : @tzid
|
11
|
+
end
|
12
|
+
|
13
|
+
def tzid=(timezone_id) #:nodoc:
|
14
|
+
timezone_id = default_tzid if timezone_id == :default
|
15
|
+
@tzid = timezone_id
|
16
|
+
reset_cached_values
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset_cached_values #:nodoc:
|
20
|
+
@timezone = @utc = @rational_tz_offset = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_timezone #:nodoc:
|
24
|
+
if @tzid == :floating
|
25
|
+
FloatingTimezone
|
26
|
+
else
|
27
|
+
timezone_finder.find_timezone(@tzid)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def timezone #:nodoc:
|
32
|
+
@timezone ||= find_timezone
|
33
|
+
end
|
34
|
+
|
35
|
+
# Determine if the receiver has a local time zone, i.e. it is not a floating time or a UTC time
|
36
|
+
def has_local_timezone?
|
37
|
+
tzid && tzid.upcase != "UTC"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return the receiver if it has a floating time zone already,
|
41
|
+
# otherwise return a DATETIME property with the same time as the receiver but with a floating time zone
|
42
|
+
def with_floating_timezone
|
43
|
+
if @tzid == nil
|
44
|
+
self
|
45
|
+
else
|
46
|
+
@date_time_value.with_floating_timezone.to_ri_cal_date_time_value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a instance that represents the time in UTC.
|
51
|
+
def utc
|
52
|
+
if has_local_timezone?
|
53
|
+
@utc ||= timezone.local_to_utc(self)
|
54
|
+
else # Already local or a floating time
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def rational_tz_offset #:nodoc:
|
60
|
+
if has_local_timezone?
|
61
|
+
@rational_tz_offset ||= timezone.rational_utc_offset(@date_time_value.to_datetime)
|
62
|
+
else
|
63
|
+
@rational_tz_offset ||= RiCal.RationalOffset[0]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Predicate indicating whether or not the instance represents a ZULU time
|
68
|
+
def utc?
|
69
|
+
tzid == "UTC"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Predicate indicating whether or not the instance represents a floating time
|
73
|
+
def floating?
|
74
|
+
tzid.nil?
|
75
|
+
end
|
76
|
+
|
77
|
+
def has_valid_tzinfo_tzid? #:nodoc:
|
78
|
+
if tzid && tzid != :floating
|
79
|
+
TZInfo::Timezone.get(tzid) rescue false
|
80
|
+
else
|
81
|
+
false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the simultaneous time in the specified zone.
|
86
|
+
def in_time_zone(new_zone)
|
87
|
+
new_zone = timezone_finder.find_timezone(new_zone)
|
88
|
+
return self if tzid == new_zone.identifier
|
89
|
+
if has_local_timezone?
|
90
|
+
new_zone.utc_to_local(utc)
|
91
|
+
elsif utc?
|
92
|
+
new_zone.utc_to_local(self)
|
93
|
+
else # Floating time
|
94
|
+
DateTime.new(timezone_finder, :value => @date_time_value, :tzid => new_zone.identifier)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|