Class: A0::TZMigration::TZVersion

Inherits:
Object
  • Object
show all
Defined in:
lib/a0/tzmigration/tzversion.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, version) ⇒ TZVersion

Returns a new instance of TZVersion.



10
11
12
13
14
15
# File 'lib/a0/tzmigration/tzversion.rb', line 10

def initialize(name, version)
  @name = name
  @version = version

  transitions
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/a0/tzmigration/tzversion.rb', line 8

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path.



8
9
10
# File 'lib/a0/tzmigration/tzversion.rb', line 8

def path
  @path
end

#versionObject (readonly)

Returns the value of attribute version.



8
9
10
# File 'lib/a0/tzmigration/tzversion.rb', line 8

def version
  @version
end

Class Method Details

.load_from_file(path) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/a0/tzmigration/tzversion.rb', line 23

def self.load_from_file(path)
  conf = A0::TZMigration.config.data_dir
  file = File.join(conf, path)

  raise "File #{path} not found at #{conf}" unless File.exist? file

  JSON.parse File.read(file)
end

.load_from_network(path) ⇒ Object



17
18
19
20
21
# File 'lib/a0/tzmigration/tzversion.rb', line 17

def self.load_from_network(path)
  url = "#{A0::TZMigration.config.base_url}/#{path}"

  JSON.parse RestClient.get(url)
end

.load_from_network_or_file(path) ⇒ Object



32
33
34
35
36
37
# File 'lib/a0/tzmigration/tzversion.rb', line 32

def self.load_from_network_or_file(path)
  load_from_network(path)
rescue StandardError => error
  warn "Unable to fetch from network, using local files (error was: #{error})"
  load_from_file(path)
end

.timezonesObject



128
129
130
# File 'lib/a0/tzmigration/tzversion.rb', line 128

def self.timezones
  @timezones = load_from_network_or_file('timezones/00-index.json')
end

.versionsObject



124
125
126
# File 'lib/a0/tzmigration/tzversion.rb', line 124

def self.versions
  @versions = load_from_network_or_file('versions/00-index.json')
end

Instance Method Details

#dataObject



39
40
41
42
43
# File 'lib/a0/tzmigration/tzversion.rb', line 39

def data
  return @data if defined? @data

  @data = TZVersion.load_from_network_or_file("timezones/#{name}.json")
end

#delta_range_list(other) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/a0/tzmigration/tzversion.rb', line 105

def delta_range_list(other) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  raise "No transitions for self #{@name}/#{@version}" if transitions.empty?
  raise "No transitions for other #{name}/#{version}" if other.transitions.empty?

  timestamp_list = (timestamps + other.timestamps).uniq.sort

  list_a = A0::TZMigration.split_range_list!(Marshal.load(Marshal.dump(timezone_ranges)), timestamp_list)
  list_b = A0::TZMigration.split_range_list!(Marshal.load(Marshal.dump(other.timezone_ranges)), timestamp_list)

  delta = []
  list_a.each_with_index do |range_a, index|
    range_b = list_b[index]

    delta << { ini: range_a[:ini], fin: range_a[:fin], off: range_b[:off] - range_a[:off] } if range_a[:off] != range_b[:off]
  end

  A0::TZMigration.timestamp_range_list!(A0::TZMigration.compact_range_list!(delta))
end

#released_atObject



45
46
47
48
49
# File 'lib/a0/tzmigration/tzversion.rb', line 45

def released_at
  return @released_at if defined? @released_at

  @released_at = Time.parse version_data['released_at']
end

#timestampsObject



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/a0/tzmigration/tzversion.rb', line 74

def timestamps
  return @timestamps if defined? @timestamps

  @timestamps = [-Float::INFINITY]
  transitions.each do |transition|
    @timestamps << transition['utc_timestamp']
  end
  @timestamps << +Float::INFINITY

  @timestamps
end

#timezone_rangesObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/a0/tzmigration/tzversion.rb', line 86

def timezone_ranges
  return @timezone_ranges if defined? @timezone_ranges

  ini = -Float::INFINITY
  fin = +Float::INFINITY

  @timezone_ranges = transitions.map do |transition|
    { ini: ini, fin: (ini = transition['utc_timestamp']), off: transition['utc_prev_offset'] }
  end

  @timezone_ranges << { ini: @timezone_ranges.last[:fin], fin: fin, off: transitions.last['utc_offset'] } unless @timezone_ranges.empty?

  @timezone_ranges
end

#timezone_ranges_timedObject



101
102
103
# File 'lib/a0/tzmigration/tzversion.rb', line 101

def timezone_ranges_timed
  A0::TZMigration.timestamp_range_list!(Marshal.dump(timezone_ranges))
end

#transitionsObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/a0/tzmigration/tzversion.rb', line 59

def transitions
  return @transitions if defined? @transitions

  if version_data['alias']
    @transitions = TZVersion.new(version_data['alias'], @version).transitions
  else
    @transitions = version_data['transitions']
    @transitions.each do |transition|
      transition['utc_time'] = Time.parse(transition['utc_time'])
    end
  end

  @transitions
end

#version_dataObject



51
52
53
54
55
56
57
# File 'lib/a0/tzmigration/tzversion.rb', line 51

def version_data
  return @version_data if defined? @version_data

  raise "Version #{@version} not found" unless (@version_data = data.dig('versions', @version))

  @version_data
end