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)


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

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) ⇒ Object

Raises:

  • (ArgumentError)


6
7
8
9
10
11
12
# File 'lib/icalendar/recurrence/time_util.rb', line 6

def datetime_to_time(datetime)
  raise ArgumentError, "Unsupported DateTime object passed (must be Icalendar::Values::DateTime#{datetime.class} passed instead)" unless supported_datetime_object?(datetime)
  offset = timezone_offset(datetime.ical_params["tzid"], moment: datetime.to_date)
  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)


78
79
80
81
82
# File 'lib/icalendar/recurrence/time_util.rb', line 78

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_date_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/icalendar/recurrence/time_util.rb', line 62

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)


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

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

#supported_time_object?(time_object) ⇒ Boolean

Returns:

  • (Boolean)


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

def supported_time_object?(time_object)
  time_object.is_a?(Time)
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



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/icalendar/recurrence/time_util.rb', line 42

def timezone_offset(tzid, options = {})
  tzid = Array(tzid).first
  options = {moment: Time.now}.merge(options)
  moment = options.fetch(:moment)
  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 => e
  nil
end

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

See #timezone_offset_at_moment



58
59
60
# File 'lib/icalendar/recurrence/time_util.rb', line 58

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

#to_time(time_object) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/icalendar/recurrence/time_util.rb', line 19

def to_time(time_object)
  if supported_time_object?(time_object)
    time_object
  elsif supported_datetime_object?(time_object)
    datetime_to_time(time_object)
  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