Class: Tilia::VObject::Property::VCard::DateAndOrTime

Inherits:
Tilia::VObject::Property show all
Defined in:
lib/tilia/v_object/property/v_card/date_and_or_time.rb

Overview

DateAndOrTime property.

This object encodes DATE-AND-OR-TIME values.

Direct Known Subclasses

Date, DateTime

Constant Summary

Constants inherited from Node

Node::PROFILE_CALDAV, Node::PROFILE_CARDDAV, Node::REPAIR

Instance Attribute Summary collapse

Attributes inherited from Tilia::VObject::Property

#group, #name, #parameters, #value

Attributes inherited from Node

#iterator, #parent

Instance Method Summary collapse

Methods inherited from Tilia::VObject::Property

#==, #[], #[]=, #add, #delete, #destroy, #initialize_copy, #json_serialize, #json_value=, #key?, #parts, #serialize, #to_s, #xml_serialize, #xml_value=

Methods inherited from Node

#==, #[], #[]=, #delete, #destroy, #each, #json_serialize, #key?, #serialize, #size, #xml_serialize

Constructor Details

#initialize(*args) ⇒ DateAndOrTime

Returns a new instance of DateAndOrTime.



323
324
325
326
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 323

def initialize(*args)
  super(*args)
  @delimiter = nil
end

Instance Attribute Details

#delimiternull|string

Field separator.

Returns:

  • (null|string)


12
13
14
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 12

def delimiter
  @delimiter
end

Instance Method Details

#date_timeTime

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 time was specified, we will always use midnight (in the default timezone) as the time.

If parts of the date were omitted, such as the year, we will grab the current values for those. So at the time of writing, if the year was omitted, we would have filled in 2014.

Returns:



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 91

def date_time
  now = ::Time.zone.now

  tz_format = now.utc_offset == 0 ? 'Z' : '%z'
  now_parts = DateTimeParser.parse_v_card_date_time(now.strftime('%Y%m%dT%H%M%S' + tz_format))
  date_parts = DateTimeParser.parse_v_card_date_time(value)

  # This sets all the missing parts to the current date/time.
  # So if the year was missing for a birthday, we're making it 'this
  # year'.
  date_parts.each do |k, v|
    date_parts[k] = now_parts[k] unless v
  end

  # Now follows a ruby Hack
  date_parts['timezone'] = '+0000' if date_parts['timezone'] == 'Z'
  done = false
  datetime = nil

  ActiveSupport::TimeZone.all.each do |tz|
    datetime = tz.parse("#{date_parts['year']}-#{date_parts['month']}-#{date_parts['date']} #{date_parts['hour']}:#{date_parts['minute']}:#{date_parts['second']}")

    next unless datetime.strftime('%z') == date_parts['timezone']

    done = true
    break
  end

  fail 'could not load correct time zone' unless done
  # End ruby hack

  datetime.freeze
  datetime
end

#date_time=(dt) ⇒ void

This method returns an undefined value.

Sets the property as a DateTime object.

Parameters:



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 63

def date_time=(dt)
  tz = dt.time_zone
  is_utc = ['UTC', 'GMT', 'Z'].include?(tz.name)

  if is_utc
    value = dt.strftime('%Y%m%dT%H%M%SZ')
  else
    # Calculating the offset.
    value = dt.strftime('%Y%m%dT%H%M%S%z')
  end

  @value = value
end

#json_valuearray

Returns the value, in the format it should be encoded for json.

This method must always return an array.

Returns:

  • (array)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 131

def json_value
  parts = DateTimeParser.parse_v_card_date_time(value)

  date_str = ''

  # Year
  if !parts['year'].nil?
    date_str += format('%02i', parts['year'])

    unless parts['month'].nil?
      # If a year and a month is set, we need to insert a separator
      # dash.
      date_str += '-'
    end
  else
    if !parts['month'].nil? || !parts['date'].nil?
      # Inserting two dashes
      date_str += '--'
    end
  end

  # Month
  if !parts['month'].nil?
    date_str += format('%02i', parts['month'])

    if parts['date']
      # If month and date are set, we need the separator dash.
      date_str += '-'
    end
  elsif parts['date']
    # If the month is empty, and a date is set, we need a 'empty
    # dash'
    date_str += '-'
  end

  # Date
  date_str += format('%02i', parts['date']) unless parts['date'].nil?

  # Early exit if we don't have a time string.
  if parts['hour'].nil? && parts['minute'].nil? && parts['second'].nil?
    return [date_str]
  end

  date_str += 'T'

  # Hour
  if !parts['hour'].nil?
    date_str += format('%02i', parts['hour'])

    date_str += ':' unless parts['minute'].nil?
  else
    # We know either minute or second _must_ be set, so we insert a
    # dash for an empty value.
    date_str += '-'
  end

  # Minute
  if !parts['minute'].nil?
    date_str += format('%02i', parts['minute'])

    date_str += ':' unless parts['second'].nil?
  elsif parts['second']
    # Dash for empty minute
    date_str += '-'
  end

  # Second
  date_str += format('%02i', parts['second']) unless parts['second'].nil?

  # Timezone
  date_str += parts['timezone'] unless parts['timezone'].nil?

  [date_str]
end

#parts=(parts) ⇒ void

This method returns an undefined value.

Sets a multi-valued property.

You may also specify DateTime objects here.

Parameters:

  • parts (array)


31
32
33
34
35
36
37
38
39
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 31

def parts=(parts)
  fail ArgumentError, 'Only one value allowed' if parts.size > 1

  if parts[0].is_a?(::Time)
    self.date_time = parts[0]
  else
    super(parts)
  end
end

#raw_mime_dir_valueString

Returns a raw mime-dir representation of the value.

Returns:

  • (String)


301
302
303
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 301

def raw_mime_dir_value
  parts.join(@delimiter)
end

#raw_mime_dir_value=(val) ⇒ void

This method returns an undefined value.

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.

Parameters:

  • val (String)


294
295
296
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 294

def raw_mime_dir_value=(val)
  self.value = val
end

#validate(options = 0) ⇒ array

Validates the node for correctness.

The following options are supported:

Node::REPAIR - May attempt to automatically repair the problem.
Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes.
Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes.

This method returns an array with detected problems. Every element has the following properties:

* level - problem level.
* message - A human-readable string describing the issue.
* node - A reference to the problematic node.

The level means:

1 - The issue was repaired (only happens if REPAIR was turned on).
2 - A warning.
3 - An error.

Parameters:

  • options (Fixnum) (defaults to: 0)

Returns:

  • (array)


306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 306

def validate(options = 0)
  messages = super(options)
  value = self.value

  begin
    DateTimeParser.parse_v_card_date_time(value)
  rescue InvalidDataException
    messages << {
      'level'   => 3,
      'message' => "The supplied value (#{value}) is not a correct DATE-AND-OR-TIME property",
      'node'    => self
    }
  end

  messages
end

#value=(value) ⇒ void

This method returns an undefined value.

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.

Parameters:



50
51
52
53
54
55
56
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 50

def value=(value)
  if value.is_a?(::Time)
    self.date_time = value
  else
    super
  end
end

#value_typeString

Returns the type of value.

This corresponds to the VALUE= parameter. Every property also has a ‘default’ valueType.

Returns:

  • (String)


20
21
22
# File 'lib/tilia/v_object/property/v_card/date_and_or_time.rb', line 20

def value_type
  'DATE-AND-OR-TIME'
end