Module: Icalendar::Recurrence::TimeUtil

Extended by:
TimeUtil
Included in:
TimeUtil
Defined in:
lib/icalendar/recurrence/time_util.rb

Instance Method Summary collapse

Instance Method Details

#date_to_time(date) ⇒ Object

Raises:

  • (ArgumentError)


20
21
22
23
# File 'lib/icalendar/recurrence/time_util.rb', line 20

def date_to_time(date)
  raise ArgumentError, "Must pass a Date object (#{date.class} passed instead)" unless supported_date_object?(date)
  Time.new(date.year, date.month, date.mday)
end

#datetime_to_time(datetime, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


11
12
13
14
15
16
17
18
# File 'lib/icalendar/recurrence/time_util.rb', line 11

def datetime_to_time(datetime, options = {})
  raise ArgumentError, "Unsupported DateTime object passed (must be Icalendar::Values::DateTime#{datetime.class} passed instead)" unless supported_datetime_object?(datetime)
  options[:moment] ||= datetime.to_date
  offset = timezone_offset(datetime.ical_params["tzid"], options)
  offset ||= datetime.strftime("%:z")

  Time.new(datetime.year, datetime.month, datetime.mday, datetime.hour, datetime.min, datetime.sec, offset)
end

#force_zone(time, tzid) ⇒ Object

Replaces the existing offset with one associated with given TZID. Does not change hour of day, only the offset. For example, if given a UTC time of 8am, the returned time object will still be 8am but in another timezone. See test for working examples.

Raises:

  • (ArgumentError)


93
94
95
96
97
# File 'lib/icalendar/recurrence/time_util.rb', line 93

def force_zone(time, tzid)
  offset = timezone_offset(tzid, moment: time)
  raise ArgumentError.new("Unknown TZID: #{tzid}") if offset.nil?
  Time.new(time.year, time.month, time.mday, time.hour, time.min, time.sec, offset)
end

#supported_activesupport_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/icalendar/recurrence/time_util.rb', line 85

def supported_activesupport_object?(time_object)
  defined?(ActiveSupport::TimeWithZone) && time_object.is_a?(ActiveSupport::TimeWithZone)
end

#supported_date_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/icalendar/recurrence/time_util.rb', line 69

def supported_date_object?(time_object)
  time_object.is_a?(Date) or time_object.is_a?(Icalendar::Values::Date)
end

#supported_datetime_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/icalendar/recurrence/time_util.rb', line 73

def supported_datetime_object?(time_object)
  time_object.is_a?(Icalendar::Values::DateTime)
end

#supported_icalendar_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/icalendar/recurrence/time_util.rb', line 77

def supported_icalendar_object?(time_object)
  time_object.is_a?(Icalendar::Values::DateTime) && supported_activesupport_object?(time_object.value)
end

#supported_time_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/icalendar/recurrence/time_util.rb', line 81

def supported_time_object?(time_object)
  time_object.is_a?(Time) || supported_activesupport_object?(time_object)
end

#timezone_offset(tzid, options = {}) ⇒ Object

Calculates offset for given timezone ID (tzid). Optional, specify a moment in time to calulcate this offset. If no moment is specified, use the current time.

# If done before daylight savings: TimeUtil.timezone_offset(“America/Los_Angeles”) => -08:00 # Or after: TimeUtil.timezone_offset(“America/Los_Angeles”, moment: Time.parse(“2014-04-01”)) => -07:00



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/icalendar/recurrence/time_util.rb', line 50

def timezone_offset(tzid, options = {})
  tzid = Array(tzid).first
  moment = options.fetch(:moment, Time.now)
  utc_moment = to_time(moment.clone).utc
  tzid = tzid.to_s.gsub(/^(["'])|(["'])$/, "")
  utc_offset =  TZInfo::Timezone.get(tzid).period_for_utc(utc_moment).utc_total_offset # this seems to work, but I feel like there is a lurking bug
  hour_offset = utc_offset/60/60
  hour_offset = "+#{hour_offset}" if hour_offset >= 0
  match = hour_offset.to_s.match(/(\+|-)(\d+)/)
  "#{match[1]}#{match[2].rjust(2, "0")}:00"
rescue TZInfo::InvalidTimezoneIdentifier
  nil
end

#timezone_to_hour_minute_utc_offset(tzid, moment = Time.now) ⇒ Object

See #timezone_offset_at_moment



65
66
67
# File 'lib/icalendar/recurrence/time_util.rb', line 65

def timezone_to_hour_minute_utc_offset(tzid, moment = Time.now)
  timezone_offset(tzid, moment: moment)
end

#to_time(time_object, options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/icalendar/recurrence/time_util.rb', line 25

def to_time(time_object, options = {})
  if supported_time_object?(time_object)
    time_object
  elsif supported_icalendar_object?(time_object)
    time_object.value
  elsif supported_datetime_object?(time_object)
    datetime_to_time(time_object, options)
  elsif supported_date_object?(time_object)
    date_to_time(time_object)
  elsif time_object.is_a?(String)
    Time.parse(time_object)
  else
    raise ArgumentError, "Unsupported time object passed: #{time_object.inspect}"
  end
end