a0-tzmigration-ruby 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Gemfile.lock +1 -1
 - data/README.md +50 -6
 - data/docs/index.md +6 -0
 - data/lib/a0/tzmigration.rb +1 -1
 - data/lib/a0/tzmigration/tzversion.rb +37 -72
 - data/lib/a0/tzmigration/util.rb +94 -0
 - data/lib/a0/tzmigration/version.rb +1 -1
 - metadata +3 -3
 - data/lib/a0/tzmigration/range_list.rb +0 -61
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 5315ca942000e3f71a8f3e37927f20b2eec0ec7a29dbd8ab71808abe76d63b24
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 8a0c381804c482cf2c04b67ad5db8f96c6ec8b71c15d8052e8a9f002f45c9806
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c64c31ad265828ed9ca784856d8261e02a24c1c60f8e0538cd2ad6dfe38925108af6a5073378148a13a43ec02a95220eb2eb0e607b70a117b020b6d4a5dc6176
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 597161ffde5f4d510ada563e354d4498458123022b9350db906482beb669de0f06efc9d8776223f87ad332f5e0b9c9dee13b73e5d359dd02d43ba40a6e051802
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,15 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # A0::TZMigration
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            TODO: Delete this and the text above, and describe your gem
         
     | 
| 
      
 3 
     | 
    
         
            +
            This gem provides utilities to help with migrations between timezone changes. Please check the official webpage for documentation:
         
     | 
| 
      
 4 
     | 
    
         
            +
            [https://a0.github.io/a0-tzmigration/](https://a0.github.io/a0-tzmigration/)
         
     | 
| 
       6 
5 
     | 
    
         | 
| 
       7 
6 
     | 
    
         
             
            ## Installation
         
     | 
| 
       8 
7 
     | 
    
         | 
| 
       9 
8 
     | 
    
         
             
            Add this line to your application's Gemfile:
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
       11 
10 
     | 
    
         
             
            ```ruby
         
     | 
| 
       12 
     | 
    
         
            -
            gem 'a0-tzmigration'
         
     | 
| 
      
 11 
     | 
    
         
            +
            gem 'a0-tzmigration-ruby'
         
     | 
| 
       13 
12 
     | 
    
         
             
            ```
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
14 
     | 
    
         
             
            And then execute:
         
     | 
| 
         @@ -18,11 +17,56 @@ And then execute: 
     | 
|
| 
       18 
17 
     | 
    
         | 
| 
       19 
18 
     | 
    
         
             
            Or install it yourself as:
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                $ gem install a0-tzmigration
         
     | 
| 
      
 20 
     | 
    
         
            +
                $ gem install a0-tzmigration-ruby
         
     | 
| 
       22 
21 
     | 
    
         | 
| 
       23 
22 
     | 
    
         
             
            ## Usage
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'a0-tzmigration-ruby'
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            # calculate changes from America/Santiago 2015a to America/Punta_Arenas 2017a
         
     | 
| 
      
 28 
     | 
    
         
            +
            version_a = A0::TZMigration::TZVersion.new('America/Santiago', '2015a')
         
     | 
| 
      
 29 
     | 
    
         
            +
            version_b = A0::TZMigration::TZVersion.new('America/Punta_Arenas', '2017a')
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            version_a.changes(version_b)
         
     | 
| 
      
 32 
     | 
    
         
            +
            # =>
         
     | 
| 
      
 33 
     | 
    
         
            +
            [{:ini_str=>"-∞", :fin_str=>"1890-01-01 04:43:40 UTC", :off_str=>"-00:00:54", :ini=>-Infinity, :fin=>-2524504580, :off=>-54},
         
     | 
| 
      
 34 
     | 
    
         
            +
             {:ini_str=>"1910-01-01 04:42:46 UTC", :fin_str=>"1910-01-10 04:42:46 UTC", :off_str=>"+00:17:14", :ini=>-1893439034, :fin=>-1892661434, :off=>1034},
         
     | 
| 
      
 35 
     | 
    
         
            +
             {:ini_str=>"1918-09-01 04:42:46 UTC", :fin_str=>"1918-09-10 04:42:46 UTC", :off_str=>"-00:42:46", :ini=>-1619983034, :fin=>-1619205434, :off=>-2566},
         
     | 
| 
      
 36 
     | 
    
         
            +
             {:ini_str=>"1946-09-01 03:00:00 UTC", :fin_str=>"1947-04-01 04:00:00 UTC", :off_str=>"+01:00:00", :ini=>-736376400, :fin=>-718056000, :off=>3600},
         
     | 
| 
      
 37 
     | 
    
         
            +
             {:ini_str=>"1947-05-22 04:00:00 UTC", :fin_str=>"1947-05-22 05:00:00 UTC", :off_str=>"+01:00:00", :ini=>-713649600, :fin=>-713646000, :off=>3600},
         
     | 
| 
      
 38 
     | 
    
         
            +
             {:ini_str=>"1988-10-02 04:00:00 UTC", :fin_str=>"1988-10-09 04:00:00 UTC", :off_str=>"-01:00:00", :ini=>591768000, :fin=>592372800, :off=>-3600},
         
     | 
| 
      
 39 
     | 
    
         
            +
             {:ini_str=>"1990-03-11 03:00:00 UTC", :fin_str=>"1990-03-18 03:00:00 UTC", :off_str=>"-01:00:00", :ini=>637124400, :fin=>637729200, :off=>-3600},
         
     | 
| 
      
 40 
     | 
    
         
            +
             {:ini_str=>"2016-05-15 03:00:00 UTC", :fin_str=>"2016-08-14 04:00:00 UTC", :off_str=>"-01:00:00", :ini=>1463281200, :fin=>1471147200, :off=>-3600}]
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            # get current known versions in the repository
         
     | 
| 
      
 44 
     | 
    
         
            +
            A0::TZMigration::TZVersion.versions
         
     | 
| 
      
 45 
     | 
    
         
            +
            # =>
         
     | 
| 
      
 46 
     | 
    
         
            +
              { "2013c" =>
         
     | 
| 
      
 47 
     | 
    
         
            +
                { "released_at" => "2013-04-19 16:17:40 -0700",
         
     | 
| 
      
 48 
     | 
    
         
            +
                  "timezones" => [
         
     | 
| 
      
 49 
     | 
    
         
            +
                    "Africa/Abidjan",
         
     | 
| 
      
 50 
     | 
    
         
            +
                    "Africa/Accra",
         
     | 
| 
      
 51 
     | 
    
         
            +
                    "Africa/Addis_Ababa",
         
     | 
| 
      
 52 
     | 
    
         
            +
                    "Africa/Algiers",
         
     | 
| 
      
 53 
     | 
    
         
            +
                    "Africa/Asmara",
         
     | 
| 
      
 54 
     | 
    
         
            +
                    …
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            # get current known timezones in the repository
         
     | 
| 
      
 58 
     | 
    
         
            +
            A0::TZMigration::TZVersion.timezones
         
     | 
| 
      
 59 
     | 
    
         
            +
            # =>
         
     | 
| 
      
 60 
     | 
    
         
            +
              { "Africa/Abidjan" =>
         
     | 
| 
      
 61 
     | 
    
         
            +
                { "versions" => [
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "2013c",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    "2013d",
         
     | 
| 
      
 64 
     | 
    
         
            +
                    "2013e",
         
     | 
| 
      
 65 
     | 
    
         
            +
                    "2013f",
         
     | 
| 
      
 66 
     | 
    
         
            +
                    "2013g",
         
     | 
| 
      
 67 
     | 
    
         
            +
                    …
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            ```
         
     | 
| 
       26 
70 
     | 
    
         | 
| 
       27 
71 
     | 
    
         
             
            ## Development
         
     | 
| 
       28 
72 
     | 
    
         | 
    
        data/docs/index.md
    CHANGED
    
    | 
         @@ -1,3 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Ruby API
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            API usage and documentation for the ruby gem and others can be found at the official webpage:
         
     | 
| 
      
 4 
     | 
    
         
            +
            [https://a0.github.io/a0-tzmigration/](https://a0.github.io/a0-tzmigration/)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       1 
7 
     | 
    
         
             
            # JSON data files
         
     | 
| 
       2 
8 
     | 
    
         | 
| 
       3 
9 
     | 
    
         
             
            All info is publicly available at the following URL:
         
     | 
    
        data/lib/a0/tzmigration.rb
    CHANGED
    
    
| 
         @@ -1,74 +1,61 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            require 'rest-client'
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
            module A0
         
     | 
| 
       6 
4 
     | 
    
         
             
              module TZMigration
         
     | 
| 
       7 
5 
     | 
    
         
             
                class TZVersion
         
     | 
| 
       8 
     | 
    
         
            -
                  attr_reader : 
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_reader :name, :version
         
     | 
| 
       9 
7 
     | 
    
         | 
| 
       10 
8 
     | 
    
         
             
                  def initialize(name, version)
         
     | 
| 
       11 
9 
     | 
    
         
             
                    @name = name
         
     | 
| 
       12 
10 
     | 
    
         
             
                    @version = version
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                    transitions
         
     | 
| 
       15 
11 
     | 
    
         
             
                  end
         
     | 
| 
       16 
12 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                  def  
     | 
| 
       18 
     | 
    
         
            -
                     
     | 
| 
      
 13 
     | 
    
         
            +
                  def data
         
     | 
| 
      
 14 
     | 
    
         
            +
                    return @data if defined? @data
         
     | 
| 
       19 
15 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
                     
     | 
| 
      
 16 
     | 
    
         
            +
                    @data = Util.load_from_network_or_file("timezones/#{name}.json")
         
     | 
| 
       21 
17 
     | 
    
         
             
                  end
         
     | 
| 
       22 
18 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
                  def  
     | 
| 
       24 
     | 
    
         
            -
                     
     | 
| 
       25 
     | 
    
         
            -
                    file = File.join(conf, path)
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                    raise "File #{path} not found at #{conf}" unless File.exist? file
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                    JSON.parse File.read(file)
         
     | 
| 
       30 
     | 
    
         
            -
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def version_data
         
     | 
| 
      
 20 
     | 
    
         
            +
                    return @version_data if defined? @version_data
         
     | 
| 
       31 
21 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                    load_from_network(path)
         
     | 
| 
       34 
     | 
    
         
            -
                  rescue StandardError => error
         
     | 
| 
       35 
     | 
    
         
            -
                    warn "Unable to fetch from network, using local files (error was: #{error})"
         
     | 
| 
       36 
     | 
    
         
            -
                    load_from_file(path)
         
     | 
| 
       37 
     | 
    
         
            -
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    raise "Version #{@version} not found for #{@name}." unless (@version_data = data.dig('versions', @version))
         
     | 
| 
       38 
23 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
                    if @version_data['alias']
         
     | 
| 
      
 25 
     | 
    
         
            +
                      @link = TZVersion.new(@version_data['alias'], @version)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @version_data = @link.version_data
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
       41 
28 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
                    @ 
     | 
| 
      
 29 
     | 
    
         
            +
                    @version_data
         
     | 
| 
       43 
30 
     | 
    
         
             
                  end
         
     | 
| 
       44 
31 
     | 
    
         | 
| 
       45 
32 
     | 
    
         
             
                  def released_at
         
     | 
| 
       46 
33 
     | 
    
         
             
                    return @released_at if defined? @released_at
         
     | 
| 
       47 
34 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                    @released_at =  
     | 
| 
      
 35 
     | 
    
         
            +
                    @released_at = version_data['released_at']
         
     | 
| 
       49 
36 
     | 
    
         
             
                  end
         
     | 
| 
       50 
37 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                  def  
     | 
| 
       52 
     | 
    
         
            -
                    return @ 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                    raise "Version #{@version} not found" unless (@version_data = data.dig('versions', @version))
         
     | 
| 
      
 38 
     | 
    
         
            +
                  def transitions
         
     | 
| 
      
 39 
     | 
    
         
            +
                    return @transitions if defined? @transitions
         
     | 
| 
       55 
40 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                    @version_data
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @transitions = version_data['transitions']
         
     | 
| 
       57 
42 
     | 
    
         
             
                  end
         
     | 
| 
       58 
43 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                  def  
     | 
| 
       60 
     | 
    
         
            -
                    return @ 
     | 
| 
      
 44 
     | 
    
         
            +
                  def transition_ranges # rubocop:disable Metrics/AbcSize
         
     | 
| 
      
 45 
     | 
    
         
            +
                    return @transition_ranges if defined? @transition_ranges
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    ini = -Float::INFINITY
         
     | 
| 
      
 48 
     | 
    
         
            +
                    fin = +Float::INFINITY
         
     | 
| 
       61 
49 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
                     
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                     
     | 
| 
       65 
     | 
    
         
            -
                       
     | 
| 
       66 
     | 
    
         
            -
                      @transitions.each do |transition|
         
     | 
| 
       67 
     | 
    
         
            -
                        transition['utc_time'] = Time.parse(transition['utc_time'])
         
     | 
| 
       68 
     | 
    
         
            -
                      end
         
     | 
| 
      
 50 
     | 
    
         
            +
                    return @transition_ranges = [Util.range_item(ini, fin, 0)] if transitions.empty?
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    @transition_ranges = transitions.map do |transition|
         
     | 
| 
      
 53 
     | 
    
         
            +
                      Util.range_item(ini, (ini = transition['utc_timestamp']), transition['utc_prev_offset'])
         
     | 
| 
       69 
54 
     | 
    
         
             
                    end
         
     | 
| 
       70 
55 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                    @transitions
         
     | 
| 
      
 56 
     | 
    
         
            +
                    @transition_ranges << Util.range_item(@transition_ranges.last[:fin], fin, transitions.last['utc_offset'])
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    @transition_ranges
         
     | 
| 
       72 
59 
     | 
    
         
             
                  end
         
     | 
| 
       73 
60 
     | 
    
         | 
| 
       74 
61 
     | 
    
         
             
                  def timestamps
         
     | 
| 
         @@ -83,50 +70,28 @@ module A0 
     | 
|
| 
       83 
70 
     | 
    
         
             
                    @timestamps
         
     | 
| 
       84 
71 
     | 
    
         
             
                  end
         
     | 
| 
       85 
72 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
                  def  
     | 
| 
       87 
     | 
    
         
            -
                     
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                    ini = -Float::INFINITY
         
     | 
| 
       90 
     | 
    
         
            -
                    fin = +Float::INFINITY
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                    @timezone_ranges = transitions.map do |transition|
         
     | 
| 
       93 
     | 
    
         
            -
                      { ini: ini, fin: (ini = transition['utc_timestamp']), off: transition['utc_prev_offset'] }
         
     | 
| 
       94 
     | 
    
         
            -
                    end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                    @timezone_ranges << { ini: @timezone_ranges.last[:fin], fin: fin, off: transitions.last['utc_offset'] } unless @timezone_ranges.empty?
         
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
                    @timezone_ranges
         
     | 
| 
       99 
     | 
    
         
            -
                  end
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                  def timezone_ranges_timed
         
     | 
| 
       102 
     | 
    
         
            -
                    A0::TZMigration.timestamp_range_list!(Marshal.dump(timezone_ranges))
         
     | 
| 
       103 
     | 
    
         
            -
                  end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                  def delta_range_list(other) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
       106 
     | 
    
         
            -
                    raise "No transitions for self #{@name}/#{@version}" if transitions.empty?
         
     | 
| 
       107 
     | 
    
         
            -
                    raise "No transitions for other #{name}/#{version}" if other.transitions.empty?
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    timestamp_list = (timestamps + other.timestamps).uniq.sort
         
     | 
| 
      
 73 
     | 
    
         
            +
                  def changes(other) # rubocop:disable Metrics/AbcSize
         
     | 
| 
      
 74 
     | 
    
         
            +
                    timestamp_list = (timestamps + other.timestamps).sort.uniq
         
     | 
| 
       110 
75 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                    list_a =  
     | 
| 
       112 
     | 
    
         
            -
                    list_b =  
     | 
| 
      
 76 
     | 
    
         
            +
                    list_a = Util.split_ranges(transition_ranges, timestamp_list)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    list_b = Util.split_ranges(other.transition_ranges, timestamp_list)
         
     | 
| 
       113 
78 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                     
     | 
| 
      
 79 
     | 
    
         
            +
                    changes = []
         
     | 
| 
       115 
80 
     | 
    
         
             
                    list_a.each_with_index do |range_a, index|
         
     | 
| 
       116 
81 
     | 
    
         
             
                      range_b = list_b[index]
         
     | 
| 
       117 
82 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                       
     | 
| 
      
 83 
     | 
    
         
            +
                      changes << Util.range_item(range_a[:ini], range_a[:fin], range_b[:off] - range_a[:off]) if range_a[:off] != range_b[:off]
         
     | 
| 
       119 
84 
     | 
    
         
             
                    end
         
     | 
| 
       120 
85 
     | 
    
         | 
| 
       121 
     | 
    
         
            -
                     
     | 
| 
      
 86 
     | 
    
         
            +
                    Util.compact_ranges!(changes)
         
     | 
| 
       122 
87 
     | 
    
         
             
                  end
         
     | 
| 
       123 
88 
     | 
    
         | 
| 
       124 
89 
     | 
    
         
             
                  def self.versions
         
     | 
| 
       125 
     | 
    
         
            -
                    @versions = load_from_network_or_file('versions/00-index.json')
         
     | 
| 
      
 90 
     | 
    
         
            +
                    @versions = Util.load_from_network_or_file('versions/00-index.json')['versions']
         
     | 
| 
       126 
91 
     | 
    
         
             
                  end
         
     | 
| 
       127 
92 
     | 
    
         | 
| 
       128 
93 
     | 
    
         
             
                  def self.timezones
         
     | 
| 
       129 
     | 
    
         
            -
                    @timezones = load_from_network_or_file('timezones/00-index.json')
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @timezones = Util.load_from_network_or_file('timezones/00-index.json')['timezones']
         
     | 
| 
       130 
95 
     | 
    
         
             
                  end
         
     | 
| 
       131 
96 
     | 
    
         
             
                end
         
     | 
| 
       132 
97 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rest-client'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module A0
         
     | 
| 
      
 6 
     | 
    
         
            +
              module TZMigration
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Util
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def self.compact_ranges!(range_list) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
      
 9 
     | 
    
         
            +
                    index = 0
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    while index < range_list.count
         
     | 
| 
      
 12 
     | 
    
         
            +
                      curr_range = range_list[index]
         
     | 
| 
      
 13 
     | 
    
         
            +
                      next_range = range_list[index + 1]
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                      if next_range && curr_range[:fin] == next_range[:ini] && curr_range[:off] == next_range[:off]
         
     | 
| 
      
 16 
     | 
    
         
            +
                        curr_range[:fin] = next_range[:fin]
         
     | 
| 
      
 17 
     | 
    
         
            +
                        curr_range[:fin_str] = next_range[:fin_str]
         
     | 
| 
      
 18 
     | 
    
         
            +
                        range_list.delete_at(index + 1)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      else
         
     | 
| 
      
 20 
     | 
    
         
            +
                        index += 1
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    range_list
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def self.offset_to_str(offset)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    str = Time.at(offset.abs).utc.strftime('%H:%M:%S')
         
     | 
| 
      
 29 
     | 
    
         
            +
                    sig = offset.negative? ? '-' : '+'
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    "#{sig}#{str}"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def self.timestamp_to_str(timestamp)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    if timestamp == -Float::INFINITY
         
     | 
| 
      
 36 
     | 
    
         
            +
                      '-∞'
         
     | 
| 
      
 37 
     | 
    
         
            +
                    elsif timestamp == +Float::INFINITY
         
     | 
| 
      
 38 
     | 
    
         
            +
                      '∞'
         
     | 
| 
      
 39 
     | 
    
         
            +
                    else
         
     | 
| 
      
 40 
     | 
    
         
            +
                      Time.at(timestamp).utc.to_s
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def self.range_item(ini, fin, off)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    { ini_str: timestamp_to_str(ini), fin_str: timestamp_to_str(fin), off_str: offset_to_str(off), ini: ini, fin: fin, off: off }
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  def self.next_index(index, range_list, timestamp)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    index += 1 while range_list[index + 1] && range_list[index][:ini] < timestamp && range_list[index][:fin] <= timestamp
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    index
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def self.split_ranges(range_list, timestamps) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
      
 55 
     | 
    
         
            +
                    range_list = Marshal.load(Marshal.dump(range_list))
         
     | 
| 
      
 56 
     | 
    
         
            +
                    index = 0
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    timestamps.each do |timestamp|
         
     | 
| 
      
 59 
     | 
    
         
            +
                      index = next_index(index, range_list, timestamp)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      range = range_list[index]
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                      if index < range_list.count && timestamp > range[:ini] && timestamp < range[:fin]
         
     | 
| 
      
 63 
     | 
    
         
            +
                        range_list.insert index + 1, range.merge(ini: timestamp)
         
     | 
| 
      
 64 
     | 
    
         
            +
                        range_list[index][:fin] = timestamp
         
     | 
| 
      
 65 
     | 
    
         
            +
                      end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    range_list
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  def self.load_from_network(path)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    url = "#{A0::TZMigration.config.base_url}/#{path}"
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    JSON.parse RestClient.get(url)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  def self.load_from_file(path)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    conf = A0::TZMigration.config.data_dir
         
     | 
| 
      
 79 
     | 
    
         
            +
                    file = File.join(conf, path)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    raise "File #{path} not found at #{conf}" unless File.exist? file
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                    JSON.parse File.read(file)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  def self.load_from_network_or_file(path)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    load_from_network(path)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  rescue StandardError => error
         
     | 
| 
      
 89 
     | 
    
         
            +
                    warn "Unable to fetch from network, using local files (error was: #{error})"
         
     | 
| 
      
 90 
     | 
    
         
            +
                    load_from_file(path)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: a0-tzmigration-ruby
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Aldrin Martoq
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2018- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-06-02 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: bundler
         
     | 
| 
         @@ -827,8 +827,8 @@ files: 
     | 
|
| 
       827 
827 
     | 
    
         
             
            - lib/a0/tzmigration/data_generator/git.rb
         
     | 
| 
       828 
828 
     | 
    
         
             
            - lib/a0/tzmigration/data_generator/process.rb
         
     | 
| 
       829 
829 
     | 
    
         
             
            - lib/a0/tzmigration/data_generator/save.rb
         
     | 
| 
       830 
     | 
    
         
            -
            - lib/a0/tzmigration/range_list.rb
         
     | 
| 
       831 
830 
     | 
    
         
             
            - lib/a0/tzmigration/tzversion.rb
         
     | 
| 
      
 831 
     | 
    
         
            +
            - lib/a0/tzmigration/util.rb
         
     | 
| 
       832 
832 
     | 
    
         
             
            - lib/a0/tzmigration/version.rb
         
     | 
| 
       833 
833 
     | 
    
         
             
            homepage: http://github.com/a0/a0-tzmigration-ruby
         
     | 
| 
       834 
834 
     | 
    
         
             
            licenses:
         
     | 
| 
         @@ -1,61 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # frozen_string_literal: true
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module A0
         
     | 
| 
       4 
     | 
    
         
            -
              module TZMigration
         
     | 
| 
       5 
     | 
    
         
            -
                def self.compact_range_list!(range_list) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
       6 
     | 
    
         
            -
                  index = 0
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                  while index < range_list.count
         
     | 
| 
       9 
     | 
    
         
            -
                    curr_range = range_list[index]
         
     | 
| 
       10 
     | 
    
         
            -
                    next_range = range_list[index + 1]
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                    if next_range && curr_range[:fin] == next_range[:ini] && curr_range[:off] == next_range[:off]
         
     | 
| 
       13 
     | 
    
         
            -
                      curr_range[:fin] = next_range[:fin]
         
     | 
| 
       14 
     | 
    
         
            -
                      range_list.delete_at(index + 1)
         
     | 
| 
       15 
     | 
    
         
            -
                    else
         
     | 
| 
       16 
     | 
    
         
            -
                      index += 1
         
     | 
| 
       17 
     | 
    
         
            -
                    end
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  range_list
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                def self.next_index(index, range_list, timestamp)
         
     | 
| 
       24 
     | 
    
         
            -
                  index += 1 while range_list[index + 1] && range_list[index][:ini] < timestamp && range_list[index][:fin] <= timestamp
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  index
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                def self.timestamp_to_utc(timestamp)
         
     | 
| 
       30 
     | 
    
         
            -
                  Time.at(timestamp).utc if timestamp && timestamp != Float::INFINITY && timestamp != -Float::INFINITY
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                def self.timestamp_range_list!(range_list)
         
     | 
| 
       34 
     | 
    
         
            -
                  range_list.each do |range|
         
     | 
| 
       35 
     | 
    
         
            -
                    range[:utc_ini] = timestamp_to_utc(range[:ini])
         
     | 
| 
       36 
     | 
    
         
            -
                    range[:utc_fin] = timestamp_to_utc(range[:fin])
         
     | 
| 
       37 
     | 
    
         
            -
                  end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  range_list
         
     | 
| 
       40 
     | 
    
         
            -
                end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                def self.split_range_list!(range_list, timestamps) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
         
     | 
| 
       43 
     | 
    
         
            -
                  index = next_index(0, range_list, timestamps.first)
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                  timestamps.each_with_index do |timestamp, timestamp_index|
         
     | 
| 
       46 
     | 
    
         
            -
                    range = range_list[index]
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                    if timestamp > range[:ini] && timestamp < range[:fin] && index < range_list.count
         
     | 
| 
       49 
     | 
    
         
            -
                      range_list.insert index + 1, range.merge(ini: timestamp)
         
     | 
| 
       50 
     | 
    
         
            -
                      range_list[index][:fin] = timestamp
         
     | 
| 
       51 
     | 
    
         
            -
                    end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                    next_timestamp = timestamps[timestamp_index + 1]
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                    index = next_index(index, range_list, next_timestamp) if next_timestamp
         
     | 
| 
       56 
     | 
    
         
            -
                  end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                  range_list
         
     | 
| 
       59 
     | 
    
         
            -
                end
         
     | 
| 
       60 
     | 
    
         
            -
              end
         
     | 
| 
       61 
     | 
    
         
            -
            end
         
     |