Module: Flycal::TimeFormat
- Defined in:
- lib/flycal/time_format.rb
Overview
Named-zone clock for template hours and every datetime Flycal emits.
Wall-clock windows (work 9:30–13, dinner 19–23, template_custom) are local to this zone — never the server process TZ (often UTC in production). JSON start/end/from/to always share that same offset.
Constant Summary collapse
- DEFAULT_ZONE =
"Europe/Rome"
Class Method Summary collapse
- .coerce(value) ⇒ Object
- .coerce_zone(name) ⇒ Object
- .current_zone ⇒ Object
- .from_calendars(calendars, calendar_ids = nil) ⇒ Object
- .iso8601(value, zone: current_zone) ⇒ Object
- .local(year, month, day, hour = 0, min = 0, sec = 0, zone: current_zone) ⇒ Object
- .now ⇒ Object
-
.resolve(explicit: nil, calendars: nil, calendar_ids: nil) ⇒ Object
explicit param → Google calendar timeZone → FLYCAL_TIMEZONE → Europe/Rome.
- .today ⇒ Object
- .unified(value, zone: current_zone) ⇒ Object
- .with_zone(name) ⇒ Object
- .zone_name(name = nil) ⇒ Object
Class Method Details
.coerce(value) ⇒ Object
108 109 110 111 112 113 114 115 116 |
# File 'lib/flycal/time_format.rb', line 108 def coerce(value) return nil if value.nil? return value if value.is_a?(Time) return value.to_time if value.respond_to?(:to_time) Time.parse(value.to_s) rescue ArgumentError nil end |
.coerce_zone(name) ⇒ Object
34 35 36 37 38 39 40 |
# File 'lib/flycal/time_format.rb', line 34 def coerce_zone(name) return name if name.is_a?(ActiveSupport::TimeZone) key = name.to_s.strip key = DEFAULT_ZONE if key.empty? ActiveSupport::TimeZone[key] || ActiveSupport::TimeZone[DEFAULT_ZONE] end |
.current_zone ⇒ Object
30 31 32 |
# File 'lib/flycal/time_format.rb', line 30 def current_zone Thread.current[:flycal_timezone] || coerce_zone(DEFAULT_ZONE) end |
.from_calendars(calendars, calendar_ids = nil) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/flycal/time_format.rb', line 66 def from_calendars(calendars, calendar_ids = nil) return nil if calendars.nil? || (calendars.respond_to?(:empty?) && calendars.empty?) ids = Array(calendar_ids).map(&:to_s) list = Array(calendars) selected = if ids.empty? list else matched = list.select { |cal| cal.respond_to?(:id) && ids.include?(cal.id.to_s) } matched.empty? ? list : matched end cal = selected.find { |c| c.respond_to?(:primary) && c.primary } || selected.first tz = cal.respond_to?(:time_zone) ? cal.time_zone : nil return nil if tz.to_s.strip.empty? zone_name(tz) end |
.iso8601(value, zone: current_zone) ⇒ Object
97 98 99 |
# File 'lib/flycal/time_format.rb', line 97 def iso8601(value, zone: current_zone) unified(value, zone: zone)&.iso8601 end |
.local(year, month, day, hour = 0, min = 0, sec = 0, zone: current_zone) ⇒ Object
93 94 95 |
# File 'lib/flycal/time_format.rb', line 93 def local(year, month, day, hour = 0, min = 0, sec = 0, zone: current_zone) coerce_zone(zone).local(year, month, day, hour, min, sec) end |
.now ⇒ Object
85 86 87 |
# File 'lib/flycal/time_format.rb', line 85 def now current_zone.now end |
.resolve(explicit: nil, calendars: nil, calendar_ids: nil) ⇒ Object
explicit param → Google calendar timeZone → FLYCAL_TIMEZONE → Europe/Rome. Never uses ENV (Docker/Kamal set that to UTC).
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/flycal/time_format.rb', line 53 def resolve(explicit: nil, calendars: nil, calendar_ids: nil) key = explicit.to_s.strip return zone_name(key) unless key.empty? from_cal = from_calendars(calendars, calendar_ids) return from_cal if from_cal env = ENV["FLYCAL_TIMEZONE"].to_s.strip return zone_name(env) unless env.empty? DEFAULT_ZONE end |
.today ⇒ Object
89 90 91 |
# File 'lib/flycal/time_format.rb', line 89 def today current_zone.today end |
.unified(value, zone: current_zone) ⇒ Object
101 102 103 104 105 106 |
# File 'lib/flycal/time_format.rb', line 101 def unified(value, zone: current_zone) time = coerce(value) return nil unless time coerce_zone(zone).at(time.to_f) end |
.with_zone(name) ⇒ Object
22 23 24 25 26 27 28 |
# File 'lib/flycal/time_format.rb', line 22 def with_zone(name) previous = Thread.current[:flycal_timezone] Thread.current[:flycal_timezone] = coerce_zone(name) yield current_zone ensure Thread.current[:flycal_timezone] = previous end |
.zone_name(name = nil) ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/flycal/time_format.rb', line 42 def zone_name(name = nil) zone = if name.nil? || name.to_s.strip.empty? current_zone else coerce_zone(name) end zone.tzinfo&.identifier || zone.name end |