rubyredrick-ri_cal 0.0.2
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 +3 -0
- data/Manifest.txt +122 -0
- data/README.txt +271 -0
- data/Rakefile +31 -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 +2 -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 +22 -0
- data/lib/ri_cal/component/calendar.rb +199 -0
- data/lib/ri_cal/component/event.rb +30 -0
- data/lib/ri_cal/component/freebusy.rb +19 -0
- data/lib/ri_cal/component/journal.rb +22 -0
- data/lib/ri_cal/component/t_z_info_timezone.rb +124 -0
- data/lib/ri_cal/component/timezone/daylight_period.rb +26 -0
- data/lib/ri_cal/component/timezone/standard_period.rb +24 -0
- data/lib/ri_cal/component/timezone/timezone_period.rb +54 -0
- data/lib/ri_cal/component/timezone.rb +193 -0
- data/lib/ri_cal/component/todo.rb +26 -0
- data/lib/ri_cal/component.rb +224 -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 +27 -0
- data/lib/ri_cal/core_extensions/date.rb +13 -0
- data/lib/ri_cal/core_extensions/date_time/conversions.rb +27 -0
- data/lib/ri_cal/core_extensions/date_time.rb +13 -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 +32 -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 +27 -0
- data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +88 -0
- data/lib/ri_cal/core_extensions/time.rb +11 -0
- data/lib/ri_cal/core_extensions.rb +6 -0
- data/lib/ri_cal/invalid_timezone_identifer.rb +20 -0
- data/lib/ri_cal/occurrence_enumerator.rb +172 -0
- data/lib/ri_cal/parser.rb +138 -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 +1526 -0
- data/lib/ri_cal/properties/freebusy.rb +594 -0
- data/lib/ri_cal/properties/journal.rb +1240 -0
- data/lib/ri_cal/properties/timezone.rb +151 -0
- data/lib/ri_cal/properties/timezone_period.rb +416 -0
- data/lib/ri_cal/properties/todo.rb +1562 -0
- data/lib/ri_cal/property_value/array.rb +19 -0
- data/lib/ri_cal/property_value/cal_address.rb +12 -0
- data/lib/ri_cal/property_value/date.rb +119 -0
- data/lib/ri_cal/property_value/date_time/additive_methods.rb +43 -0
- data/lib/ri_cal/property_value/date_time/time_machine.rb +180 -0
- data/lib/ri_cal/property_value/date_time/timezone_support.rb +65 -0
- data/lib/ri_cal/property_value/date_time.rb +324 -0
- data/lib/ri_cal/property_value/duration.rb +106 -0
- data/lib/ri_cal/property_value/geo.rb +12 -0
- data/lib/ri_cal/property_value/integer.rb +13 -0
- data/lib/ri_cal/property_value/occurrence_list.rb +82 -0
- data/lib/ri_cal/property_value/period.rb +63 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +98 -0
- data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +77 -0
- data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +149 -0
- data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +54 -0
- data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +32 -0
- data/lib/ri_cal/property_value/recurrence_rule/occurence_incrementer.rb +794 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +132 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +61 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +34 -0
- data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +50 -0
- data/lib/ri_cal/property_value/recurrence_rule/validations.rb +126 -0
- data/lib/ri_cal/property_value/recurrence_rule.rb +146 -0
- data/lib/ri_cal/property_value/text.rb +41 -0
- data/lib/ri_cal/property_value/uri.rb +12 -0
- data/lib/ri_cal/property_value/utc_offset.rb +34 -0
- data/lib/ri_cal/property_value.rb +110 -0
- data/lib/ri_cal/required_timezones.rb +56 -0
- data/lib/ri_cal/time_with_floating_timezone.rb +59 -0
- data/lib/ri_cal.rb +134 -0
- data/ri_cal.gemspec +47 -0
- data/sample_ical_files/from_ical_dot_app/test1.ics +38 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/spec/ri_cal/component/alarm_spec.rb +13 -0
- data/spec/ri_cal/component/calendar_spec.rb +55 -0
- data/spec/ri_cal/component/event_spec.rb +157 -0
- data/spec/ri_cal/component/freebusy_spec.rb +13 -0
- data/spec/ri_cal/component/journal_spec.rb +13 -0
- data/spec/ri_cal/component/t_z_info_timezone_spec.rb +37 -0
- data/spec/ri_cal/component/timezone_spec.rb +155 -0
- data/spec/ri_cal/component/todo_spec.rb +61 -0
- data/spec/ri_cal/component_spec.rb +212 -0
- data/spec/ri_cal/core_extensions/time/calculations_spec.rb +189 -0
- data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +46 -0
- data/spec/ri_cal/occurrence_enumerator_spec.rb +218 -0
- data/spec/ri_cal/parser_spec.rb +304 -0
- data/spec/ri_cal/property_value/date_spec.rb +22 -0
- data/spec/ri_cal/property_value/date_time_spec.rb +448 -0
- data/spec/ri_cal/property_value/duration_spec.rb +80 -0
- data/spec/ri_cal/property_value/period_spec.rb +50 -0
- data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +22 -0
- data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1815 -0
- data/spec/ri_cal/property_value/text_spec.rb +14 -0
- data/spec/ri_cal/property_value/utc_offset_spec.rb +49 -0
- data/spec/ri_cal/property_value_spec.rb +111 -0
- data/spec/ri_cal/required_timezones_spec.rb +68 -0
- data/spec/ri_cal_spec.rb +54 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +24 -0
- data/tasks/ri_cal.rake +403 -0
- data/tasks/spec.rake +35 -0
- metadata +201 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale
|
4
|
+
#- All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
class Array < PropertyValue # :nodoc:
|
7
|
+
|
8
|
+
def value=(val)
|
9
|
+
case val
|
10
|
+
when String
|
11
|
+
@value = val.split(",")
|
12
|
+
else
|
13
|
+
@value = val
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale
|
4
|
+
#- All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# RiCal::PropertyValue::CalAddress represents an icalendar CalAddress property value
|
7
|
+
# which is defined in
|
8
|
+
# RFC 2445 section 4.3.3 p 34
|
9
|
+
class CalAddress < PropertyValue
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'date'
|
2
|
+
module RiCal
|
3
|
+
class PropertyValue
|
4
|
+
#- ©2009 Rick DeNatale
|
5
|
+
#- All rights reserved. Refer to the file README.txt for the license
|
6
|
+
#
|
7
|
+
# RiCal::PropertyValue::CalAddress represents an icalendar Date property value
|
8
|
+
# which is defined in
|
9
|
+
# RFC 2445 section 4.3.4 p 34
|
10
|
+
class Date < PropertyValue
|
11
|
+
# Returns the value of the reciever as an RFC 2445 iCalendar string
|
12
|
+
def value
|
13
|
+
if @date_time_value
|
14
|
+
@date_time_value.strftime("%Y%m%d")
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set the value of the property to val
|
21
|
+
#
|
22
|
+
# val may be either:
|
23
|
+
#
|
24
|
+
# * A string which can be parsed as a DateTime
|
25
|
+
# * A Time instance
|
26
|
+
# * A Date instance
|
27
|
+
# * A DateTime instance
|
28
|
+
def value=(val)
|
29
|
+
case val
|
30
|
+
when nil
|
31
|
+
@date_time_value = nil
|
32
|
+
when String
|
33
|
+
@date_time_value = ::DateTime.parse(::DateTime.parse(val).strftime("%Y%m%d"))
|
34
|
+
when ::Time, ::Date, ::DateTime
|
35
|
+
@date_time_value = ::DateTime.parse(val.strftime("%Y%m%d"))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def visible_params #:nodoc:
|
40
|
+
{"VALUE" => "DATE"}.merge(params)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the year (including the century)
|
44
|
+
def year
|
45
|
+
@date_time_value.year
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the month of the year (1..12)
|
49
|
+
def month
|
50
|
+
@date_time_value.month
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the day of the month
|
54
|
+
def day
|
55
|
+
@date_time_value.day
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the ruby representation a ::Date
|
59
|
+
def ruby_value
|
60
|
+
::Date.parse(@date_time_value.strftime("%Y%m%d"))
|
61
|
+
end
|
62
|
+
|
63
|
+
alias_method :to_ri_cal_ruby_value, :ruby_value
|
64
|
+
|
65
|
+
# Return an instance of RiCal::PropertyValue::DateTime representing the start of this date
|
66
|
+
def to_ri_cal_date_time_value
|
67
|
+
PropertyValue::DateTime.new(:value => @date_time_value)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return this date property
|
71
|
+
def to_ri_cal_date_value
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Return the "Natural' property value for the date_property, in this case the date property itself."
|
76
|
+
def to_ri_cal_date_or_date_time_value
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def compute_change(d, options) #:nodoc:
|
81
|
+
::Date.civil((options[:year] || d.year), (options[:month] || d.month), (options[:day] || d.day))
|
82
|
+
end
|
83
|
+
|
84
|
+
def compute_advance(d, options) #:nodoc:
|
85
|
+
d = d >> options[:years] * 12 if options[:years]
|
86
|
+
d = d >> options[:months] if options[:months]
|
87
|
+
d = d + options[:weeks] * 7 if options[:weeks]
|
88
|
+
d = d + options[:days] if options[:days]
|
89
|
+
compute_change(@date_time_value, :year => d.year, :month => d.month, :day => d.day)
|
90
|
+
end
|
91
|
+
|
92
|
+
def advance(options) #:nodoc:
|
93
|
+
PropertyValue::Date.new(timezone_finder, :value => compute_advance(@date_time_value, options), :params =>(params ? params.dup : nil) )
|
94
|
+
end
|
95
|
+
|
96
|
+
def change(options) #:nodoc:
|
97
|
+
PropertyValue::Date.new(timezone_finder,:value => compute_change(@date_time_value, options), :params => (params ? params.dup : nil) )
|
98
|
+
end
|
99
|
+
|
100
|
+
def add_date_times_to(required_timezones) #:nodoc:
|
101
|
+
# Do nothing since dates don't have a timezone
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Delegate unknown messages to the wrappered Date instance.
|
106
|
+
# TODO: Is this really necessary?
|
107
|
+
def method_missing(selector, *args) #:nodoc:
|
108
|
+
@date_time_value.send(selector, *args)
|
109
|
+
end
|
110
|
+
|
111
|
+
# TODO: consider if this should be a period rather than a hash
|
112
|
+
def occurrence_hash(default_duration) #:nodoc:
|
113
|
+
date_time = self.to_ri_cal_date_time_value
|
114
|
+
{:start => date_time,
|
115
|
+
:end => date_time.advance(:hours => 24, :seconds => -1)}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale
|
4
|
+
#- 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
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale
|
4
|
+
#- 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
|
+
def compute_change(d, options) # :nodoc:
|
9
|
+
::DateTime.civil(
|
10
|
+
options[:year] || d.year,
|
11
|
+
options[:month] || d.month,
|
12
|
+
options[:day] || d.day,
|
13
|
+
options[:hour] || d.hour,
|
14
|
+
options[:min] || (options[:hour] ? 0 : d.min),
|
15
|
+
options[:sec] || ((options[:hour] || options[:min]) ? 0 : d.sec),
|
16
|
+
options[:offset] || d.offset,
|
17
|
+
options[:start] || d.start
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def compute_advance(d, options) # :nodoc:
|
22
|
+
d = d >> options[:years] * 12 if options[:years]
|
23
|
+
d = d >> options[:months] if options[:months]
|
24
|
+
d = d + options[:weeks] * 7 if options[:weeks]
|
25
|
+
d = d + options[:days] if options[:days]
|
26
|
+
datetime_advanced_by_date = compute_change(@date_time_value, :year => d.year, :month => d.month, :day => d.day)
|
27
|
+
seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
|
28
|
+
seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date + Rational(seconds_to_advance.round, 86400)
|
29
|
+
end
|
30
|
+
|
31
|
+
def advance(options) # :nodoc:
|
32
|
+
PropertyValue::DateTime.new(timezone_finder,
|
33
|
+
:value => compute_advance(@date_time_value, options),
|
34
|
+
:tzid => tzid,
|
35
|
+
:params =>(params ? params.dup : nil)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def change(options) # :nodoc:
|
40
|
+
PropertyValue::DateTime.new(timezone_finder,
|
41
|
+
:value => compute_change(@date_time_value, options),
|
42
|
+
:tzid => tzid,
|
43
|
+
:params => (params ? params.dup : nil)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def change_sec(new_sec) #:nodoc:
|
48
|
+
PropertyValue::DateTime.civil(self.year, self.month, self.day, self.hour, self.min, sec, self.offset, self.start, params)
|
49
|
+
end
|
50
|
+
|
51
|
+
def change_min(new_min) #:nodoc:
|
52
|
+
PropertyValue::DateTime.civil(self.year, self.month, self.day, self.hour, new_min, self.sec, self.offset, self.start, params)
|
53
|
+
end
|
54
|
+
|
55
|
+
def change_hour(new_hour) #:nodoc:
|
56
|
+
PropertyValue::DateTime.civil(self.year, self.month, self.day, new_hour, self.min, self.sec, self.offset, self.start, params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def change_day(new_day) #:nodoc:
|
60
|
+
PropertyValue::DateTime.civil(self.year, self.month, new_day, self.hour, self.min, self.sec, self.offset, self.start, params)
|
61
|
+
end
|
62
|
+
|
63
|
+
def change_month(new_month) #:nodoc:
|
64
|
+
PropertyValue::DateTime.civil(self.year, new_month, self.day, self.hour, self.min, self.sec, self.offset, self.start, params)
|
65
|
+
end
|
66
|
+
|
67
|
+
def change_year(new_year) #:nodoc:
|
68
|
+
PropertyValue::DateTime.civil(new_year, self.month, self.day, self.hour, self.min, self.sec, self.offset, self.start, params)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Return a DATE-TIME property representing the receiver on a different day (if necessary) so that
|
72
|
+
# the result is within the 7 days starting with date
|
73
|
+
def in_week_starting?(date)
|
74
|
+
wkst_jd = date.jd
|
75
|
+
@date_time_value.jd.between?(wkst_jd, wkst_jd + 6)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return a DATE-TIME property representing the receiver on a different day (if necessary) so that
|
79
|
+
# the result is the first day of the ISO week starting on the wkst day containing the receiver.
|
80
|
+
def at_start_of_week_with_wkst(wkst)
|
81
|
+
date = @date_time_value.start_of_week_with_wkst(wkst)
|
82
|
+
change(:year => date.year, :month => date.month, :day => date.day)
|
83
|
+
end
|
84
|
+
# Return a DATE_TIME value representing the first second of the minute containing the receiver
|
85
|
+
def start_of_minute
|
86
|
+
change(:sec => 0)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Return a DATE_TIME value representing the last second of the minute containing the receiver
|
90
|
+
def end_of_minute
|
91
|
+
change(:sec => 59)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return a DATE_TIME value representing the first second of the hour containing the receiver
|
95
|
+
def start_of_hour
|
96
|
+
change(:min => 0, :sec => 0)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return a DATE_TIME value representing the last second of the hour containing the receiver
|
100
|
+
def end_of_hour
|
101
|
+
change(:min => 59, :sec => 59)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Return a DATE_TIME value representing the first second of the day containing the receiver
|
105
|
+
def start_of_day
|
106
|
+
change(:hour => 0, :min => 0, :sec => 0)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return a DATE_TIME value representing the last second of the day containing the receiver
|
110
|
+
def end_of_day
|
111
|
+
change(:hour => 23, :min => 59, :sec => 59)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Return a Ruby Date representing the first day of the ISO week starting with wkst containing the receiver
|
115
|
+
def start_of_week_with_wkst(wkst)
|
116
|
+
@date_time_value.start_of_week_with_wkst(wkst)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Return a DATE_TIME value representing the last second of the ISO week starting with wkst containing the receiver
|
120
|
+
def end_of_week_with_wkst(wkst)
|
121
|
+
date = at_start_of_week_with_wkst(wkst).advance(:days => 6).end_of_day
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return a DATE_TIME value representing the first second of the month containing the receiver
|
125
|
+
def start_of_month
|
126
|
+
change(:day => 1, :hour => 0, :min => 0, :sec => 0)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Return a DATE_TIME value representing the last second of the month containing the receiver
|
130
|
+
def end_of_month
|
131
|
+
change(:day => days_in_month, :hour => 23, :min => 59, :sec => 59)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Return a DATE_TIME value representing the first second of the month containing the receiver
|
135
|
+
def start_of_year
|
136
|
+
change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Return a DATE_TIME value representing the last second of the month containing the receiver
|
140
|
+
def end_of_year
|
141
|
+
change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return a DATE_TIME value representing the same time on the first day of the ISO year with weeks
|
145
|
+
# starting on wkst containing the receiver
|
146
|
+
def at_start_of_iso_year(wkst)
|
147
|
+
start_of_year = @date_time_value.iso_year_start(wkst)
|
148
|
+
change(:year => start_of_year.year, :month => start_of_year.month, :day => start_of_year.day)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Return a DATE_TIME value representing the same time on the last day of the ISO year with weeks
|
152
|
+
# starting on wkst containing the receiver
|
153
|
+
def at_end_of_iso_year(wkst)
|
154
|
+
num_weeks = @date_time_value.iso_weeks_in_year(wkst)
|
155
|
+
at_start_of_iso_year(wkst).advance(:weeks => (num_weeks - 1), :days => 6)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Return a DATE_TIME value representing the same time on the first day of the ISO year with weeks
|
159
|
+
# starting on wkst after the ISO year containing the receiver
|
160
|
+
def at_start_of_next_iso_year(wkst)
|
161
|
+
num_weeks = @date_time_value.iso_weeks_in_year(wkst)
|
162
|
+
at_start_of_iso_year(wkst).advance(:weeks => num_weeks)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Return a DATE_TIME value representing the last second of the last day of the ISO year with weeks
|
166
|
+
# starting on wkst containing the receiver
|
167
|
+
def end_of_iso_year(wkst)
|
168
|
+
at_end_of_iso_year(wkst).end_of_day
|
169
|
+
end
|
170
|
+
|
171
|
+
# Return a DATE-TIME representing the same time, on the same day of the month in month.
|
172
|
+
# If the month of the receiver has more days than the target month the last day of the target month
|
173
|
+
# will be used.
|
174
|
+
def in_month(month)
|
175
|
+
first = change(:day => 1, :month => month)
|
176
|
+
first.change(:day => [first.days_in_month, day].min)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RiCal
|
2
|
+
class PropertyValue
|
3
|
+
#- ©2009 Rick DeNatale
|
4
|
+
#- All rights reserved. Refer to the file README.txt for the license
|
5
|
+
#
|
6
|
+
# Time zone related ethods 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
|
11
|
+
end
|
12
|
+
|
13
|
+
def tzid=(string) #:nodoc:
|
14
|
+
@tzid = string
|
15
|
+
@timezone = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def timezone #:nodoc:
|
19
|
+
@timezone ||= timezone_finder.find_timezone(@tzid)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Determine if the receiver has a local time zone, i.e. it is not a floating time or a UTC time
|
23
|
+
def has_local_timezone?
|
24
|
+
tzid && tzid != "UTC"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return the receiver if it has a floating time zone already,
|
28
|
+
# otherwise return a DATETIME property with the same time as the receiver but with a floating time zone
|
29
|
+
def with_floating_timezone
|
30
|
+
if @tzid == nil
|
31
|
+
self
|
32
|
+
else
|
33
|
+
@date_time_value.with_floating_timezone.to_ri_cal_date_time_value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns a instance that represents the time in UTC.
|
38
|
+
def utc
|
39
|
+
if has_local_timezone?
|
40
|
+
timezone.local_to_utc(self)
|
41
|
+
else # Already local or a floating time
|
42
|
+
self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Predicate indicating whether or not the instance represents a ZULU time
|
47
|
+
def utc?
|
48
|
+
tzid == "UTC"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the simultaneous time in the specified zone.
|
52
|
+
def in_time_zone(new_zone)
|
53
|
+
new_zone = timezone_finder.find_timezone(new_zone)
|
54
|
+
return self if tzid == new_zone.identifier
|
55
|
+
if has_local_timezone?
|
56
|
+
new_zone.utc_to_local(utc)
|
57
|
+
elsif utc?
|
58
|
+
new_zone.utc_to_local(self)
|
59
|
+
else # Floating time
|
60
|
+
DateTime.new(timezone_finder, :value => @date_time_value, :tzid => new_zone.identifier)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|