class Tilia::VObject::Property::ICalendar::DateTime
DateTime
property.
This object represents DATE-TIME values, as defined here:
tools.ietf.org/html/rfc5545#section-3.3.4
This particular object has a bit of hackish magic that it may also in some cases represent a DATE value. This is because it's a common usecase to be able to change a DATE-TIME into a DATE.
Attributes
In case this is a multi-value property. This string will be used as a delimiter.
@return [String, nil]
Public Class Methods
Tilia::VObject::Property::new
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 245 def initialize(*args) super @delimiter = ',' @raw_values = [] end
Public Instance Methods
We need to intercept offsetSet, because it may be used to alter the VALUE from DATE-TIME to DATE or vice-versa.
@param [String] name @param value
@return [void]
Tilia::VObject::Property#[]=
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 208 def []=(name, value) super return nil unless name.upcase == 'VALUE' # This will ensure that dates are correctly encoded. update_date_times(date_times) end
Returns a date-time value.
Note that if this property contained more than 1 date-time, only the first will be returned. To get an array with multiple values, call getDateTimes.
If no timezone information is known, because it's either an all-day property or floating time, we will use the DateTimeZone argument to figure out the exact date.
@param [ActiveSupport::TimeZone] time_zone
@return [Time]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 101 def date_time(time_zone = nil) dt = date_times(time_zone) return nil unless dt dt[0] end
Sets the property as a DateTime
object.
@param [Time] dt @param [Boolean] isFloating If set to true, timezones will be ignored.
@return [void]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 137 def date_time=(dt) self.date_times = [dt] end
Returns multiple date-time values.
If no timezone information is known, because it's either an all-day property or floating time, we will use the DateTimeZone argument to figure out the exact date.
@param [ActiveSupport::TimeZone] time_zone
@return [DateTimeImmutable @return [DateTime
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 118 def date_times(time_zone = nil) # Does the property have a TZID? tzid = self['TZID'] time_zone = Tilia::VObject::TimeZoneUtil.time_zone(tzid.to_s, @root) if tzid dts = [] parts.each do |part| dts << Tilia::VObject::DateTimeParser.parse(part, time_zone) end dts end
Sets the property as multiple date-time objects.
The first value will be used as a reference for the timezones, and all the otehr values will be adjusted for that timezone
@param [DateTimeInterface dt @param [Boolean] isFloating If set to true, timezones will be ignored.
@return [void]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 150 def date_times=(dt) update_date_times(dt) end
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 291 def floating floating? end
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 295 def floating=(is_floating) update_date_times(date_times, is_floating) end
Returns true if this is a floating DATE or DATE-TIME.
Note that DATE is always floating.
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 84 def floating? !self.time? || (!self.key?('TZID') && !value.index('Z')) end
Returns the value, in the format it should be encoded for JSON.
This method must always return an array.
@return [array]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 169 def json_value dts = date_times tz = dts[0].time_zone is_utc = floating? ? false : ['UTC', 'GMT', 'Z'].include?(tz.name) dts.map do |dt| if time? dt.strftime('%Y-%m-%dT%H:%M:%S') + (is_utc ? 'Z' : '') else dt.strftime('%Y-%m-%d') end end end
Sets the json value, as it would appear in a jCard or jCal object.
The value must always be an array.
@param [array] value
@return [void]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 191 def json_value=(value) # dates and times in jCal have one difference to dates and times in # iCalendar. In jCal date-parts are separated by dashes, and # time-parts are separated by colons. It makes sense to just remove # those. self.value = value.map do |item| item.delete(':').delete('-') end end
Sets a multi-valued property.
You may also specify DateTime
objects here.
@param [array] parts
@return [void]
Tilia::VObject::Property#parts=
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 28 def parts=(parts) if parts[0].is_a?(::Time) self.date_times = parts else super(parts) end end
Returns a raw mime-dir representation of the value.
@return [String]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 70 def raw_mime_dir_value parts.join(@delimiter) end
Sets a raw value coming from a mimedir (iCalendar/vCard) file.
This has been 'unfolded', so only 1 line will be passed. Unescaping is not yet done, but parameters are not included.
@param [String] val
@return [void]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 63 def raw_mime_dir_value=(val) self.value = val.split(@delimiter) end
Returns true if this is a DATE-TIME value, false if it's a DATE.
@return [Boolean]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 77 def time? self['VALUE'].to_s.upcase != 'DATE' end
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 251 def update_date_times(dt, is_floating = false) values = [] if time? tz = nil is_utc = false dt.each do |d| if is_floating values << d.strftime('%Y%m%dT%H%M%S') next end if tz.nil? tz = d.time_zone is_utc = ['UTC', 'GMT', 'Z', '+00:00'].include?(tz.name) self['TZID'] = tz.name unless is_utc else d = d.in_time_zone(tz) end if is_utc values << d.strftime('%Y%m%dT%H%M%SZ') else values << d.strftime('%Y%m%dT%H%M%S') end end delete('TZID') if is_utc || is_floating else dt.each do |d| values << d.strftime('%Y%m%d') end delete('TZID') end @value = values end
(see Component#validate
)
Tilia::VObject::Property#validate
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 218 def validate(options = 0) messages = super(options) value_type = self.value_type values = parts begin save_val = nil values.each do |value| save_val = value case value_type when 'DATE' Tilia::VObject::DateTimeParser.parse_date(value) when 'DATE-TIME' Tilia::VObject::DateTimeParser.parse_date_time(value) end end rescue InvalidDataException messages << { 'level' => 3, 'message' => "The supplied value (#{save_val}) is not a correct #[value_type}", 'node' => self } end messages end
Updates the current value.
This may be either a single, or multiple strings in an array.
Instead of strings, you may also use DateTime
here.
@param [String|array|DateTimeInterface] value
@return [void]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 45 def value=(value) if value.is_a?(Array) && value[0].is_a?(::Time) self.date_times = value elsif value.is_a?(::Time) self.date_times = [value] else super(value) end end
Returns the type of value.
This corresponds to the VALUE= parameter. Every property also has a 'default' valueType.
@return [String]
# File lib/tilia/v_object/property/i_calendar/date_time.rb, line 160 def value_type time? ? 'DATE-TIME' : 'DATE' end