Class: Data::Zone

Inherits:
Object
  • Object
show all
Defined in:
lib/barometer/data/zone.rb

Overview

A simple Zone class

Used for building and converting timezone aware date and times Really, these are just wrappers for TZInfo conversions plus some extras.

Constant Summary collapse

@@zone_codes_file =
File.expand_path(
File.join(File.dirname(__FILE__), '..', 'translations', 'zone_codes.yml'))
@@zone_codes =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(zone) ⇒ Zone

Returns a new instance of Zone.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/barometer/data/zone.rb', line 20

def initialize(zone)
  if Data::Zone.is_zone_full?(zone)
    @zone_full = zone
    @tz = TZInfo::Timezone.get(zone)
  elsif Data::Zone.is_zone_offset?(zone)
    @zone_offset = zone
  elsif Data::Zone.is_zone_code?(zone)
    @zone_code = zone
  else
    raise(ArgumentError, "invalid time zone")
  end
end

Instance Attribute Details

#tzObject

Returns the value of attribute tz.



18
19
20
# File 'lib/barometer/data/zone.rb', line 18

def tz
  @tz
end

#zone_codeObject

Returns the value of attribute zone_code.



18
19
20
# File 'lib/barometer/data/zone.rb', line 18

def zone_code
  @zone_code
end

#zone_fullObject

Returns the value of attribute zone_full.



18
19
20
# File 'lib/barometer/data/zone.rb', line 18

def zone_full
  @zone_full
end

#zone_offsetObject

Returns the value of attribute zone_offset.



18
19
20
# File 'lib/barometer/data/zone.rb', line 18

def zone_offset
  @zone_offset
end

Class Method Details

._load_zone_codesObject



135
136
137
138
# File 'lib/barometer/data/zone.rb', line 135

def self._load_zone_codes
  $:.unshift(File.dirname(__FILE__))
  @@zone_codes ||= YAML.load_file(@@zone_codes_file)
end

.is_zone_code?(zone) ⇒ Boolean

Class Methods

Returns:

  • (Boolean)


101
102
103
104
105
# File 'lib/barometer/data/zone.rb', line 101

def self.is_zone_code?(zone)
  return false unless (zone && zone.is_a?(String))
  _load_zone_codes unless @@zone_codes
  Time.zone_offset(zone) || (@@zone_codes && @@zone_codes.has_key?(zone))
end

.is_zone_full?(zone) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
110
# File 'lib/barometer/data/zone.rb', line 107

def self.is_zone_full?(zone)
  return false unless (zone && zone.is_a?(String))
  zone.match(/[A-Za-z]+\/[A-Za-z]+/) ? true : false
end

.is_zone_offset?(zone) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
# File 'lib/barometer/data/zone.rb', line 112

def self.is_zone_offset?(zone)
  return false unless (zone && (zone.is_a?(Fixnum) || zone.is_a?(Float)))
  zone.to_f.abs <= 14
end

.zone_to_offset(timezone) ⇒ Object

Known conflicts IRT (ireland and india) CST (central standard time, china standard time)



122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/barometer/data/zone.rb', line 122

def self.zone_to_offset(timezone)
  offset = 0
  seconds_in_hour = 60*60
  # try to use Time
  unless offset = Time.zone_offset(timezone)
    # that would have been too easy, do it manually
    # http://www.timeanddate.com/library/abbreviations/timezones/
    # http://www.worldtimezone.com/wtz-names/timezonenames.html
    offset = (@@zone_codes[timezone.to_s.upcase] || 0) * seconds_in_hour
  end
  offset
end

Instance Method Details

#codeObject

what is the Timezone Short Code for the current timezone



38
39
40
41
42
# File 'lib/barometer/data/zone.rb', line 38

def code
  return @zone_code if @zone_code
  return nil unless @tz
  @tz.period_for_utc(Time.now.utc).zone_identifier.to_s
end

#currentObject



33
34
35
# File 'lib/barometer/data/zone.rb', line 33

def current
  @zone_full || @zone_offset || @zone_code
end

#dst?Boolean

is the current timezone in daylights savings mode?

Returns:

  • (Boolean)


58
59
60
61
# File 'lib/barometer/data/zone.rb', line 58

def dst?
  return nil unless @tz
  @tz.period_for_utc(Time.now.utc).dst?
end

#fullObject



44
45
46
# File 'lib/barometer/data/zone.rb', line 44

def full
  @zone_full || nil
end

#local_to_utc(local_time) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/barometer/data/zone.rb', line 79

def local_to_utc(local_time)
  if @zone_full
    @tz.local_to_utc(local_time)
  elsif @zone_offset || @zone_code
    local_time -= self.offset
    Time.utc(local_time.year,local_time.month,local_time.day,
      local_time.hour,local_time.min,local_time.sec)
  end
end

#now(convert = false) ⇒ Object

return Time.now.utc for the set timezone



64
65
66
67
68
69
70
71
# File 'lib/barometer/data/zone.rb', line 64

def now(convert=false)
  if @zone_full
    now = @tz.utc_to_local(Time.now.utc)
  elsif @zone_offset || @zone_code
    now = Time.now.utc + self.offset
  end
  convert ? Data::LocalTime.parse(now) : now
end

#offsetObject



48
49
50
51
52
53
54
55
# File 'lib/barometer/data/zone.rb', line 48

def offset
  if @zone_offset
    @zone_offset.to_f * 60 * 60
  elsif @zone_code
    Data::Zone.zone_to_offset(@zone_code)
  elsif @zone_full
  end
end

#todayObject

return Date.today for the set timezone



74
75
76
77
# File 'lib/barometer/data/zone.rb', line 74

def today
  now = self.now
  Date.new(now.year, now.month, now.day)
end

#utc_to_local(utc_time) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/barometer/data/zone.rb', line 89

def utc_to_local(utc_time)
  if @zone_full
    @tz.utc_to_local(utc_time)
  elsif @zone_offset || @zone_code
    utc_time + self.offset
  end
end