lib/tzinfo/data/tzdataparser.rb in tzinfo-data-1.2014.5 vs lib/tzinfo/data/tzdataparser.rb in tzinfo-data-1.2014.6

- old
+ new

@@ -6,25 +6,20 @@ # Utility methods used by TZDataParser and associated classes. # # @private module TZDataParserUtils #:nodoc: - - begin - Encoding - SUPPORTS_ENCODING = true - rescue NameError - SUPPORTS_ENCODING = false - end - - if SUPPORTS_ENCODING + # Wrapper for File.open that supports passing hash options for specifying + # encodings on Ruby 1.9+. The options are ignored on earlier versions of + # Ruby. + if RUBY_VERSION =~ /\A1\.[0-8]\./ def open_file(file_name, mode, opts, &block) - File.open(file_name, mode, opts, &block) + File.open(file_name, mode, &block) end else def open_file(file_name, mode, opts, &block) - File.open(file_name, mode, &block) + File.open(file_name, mode, opts, &block) end end private :open_file @@ -281,17 +276,17 @@ end end end end - # Loads countries from iso3166.tab and zone.tab and stores the result in - # the countries instance variable. + # Loads countries from iso3166.tab and zone1970.tab and stores the + # result in the countries instance variable. def load_countries puts 'load_countries' - # Files are in ASCII, but may change to UTF-8 (a superset of ASCII) - # in the future. + # iso3166.tab is ASCII encoded, but is planned to change to UTF-8 (a + # superset of ASCII) in the future. open_file(File.join(@input_dir, 'iso3166.tab'), 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file| file.each_line do |line| if line =~ /^([A-Z]{2})\t(.*)$/ code = $1 @@ -299,37 +294,55 @@ @countries[code] = TZDataCountry.new(code, name) end end end - # Files are in ASCII, but may change to UTF-8 (a superset of ASCII) - # in the future. - open_file(File.join(@input_dir, 'zone.tab'), 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file| + primary_zones = {} + secondary_zones = {} + + # zone1970.tab is UTF-8 encoded. + open_file(File.join(@input_dir, 'zone1970.tab'), 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file| file.each_line do |line| line.chomp! - if line =~ /^([A-Z]{2})\t([^\t]+)\t([^\t]+)(\t(.*))?$/ - code = $1 + if line =~ /^([A-Z]{2}(?:,[A-Z]{2})*)\t([^\t]+)\t([^\t]+)(\t(.*))?$/ + codes = $1 location_str = $2 zone_name = $3 description = $5 - - country = @countries[code] - raise "Country not found: #{code}" if country.nil? location = TZDataLocation.new(location_str) zone = @zones[zone_name] raise "Zone not found: #{zone_name}" if zone.nil? description = nil if description == '' - country.add_zone(TZDataCountryTimezone.new(zone, description, location)) + country_timezone = TZDataCountryTimezone.new(zone, description, location) + + codes = codes.split(',') + + (primary_zones[codes.first] ||= []) << country_timezone + + codes[1..-1].each do |code| + (secondary_zones[code] ||= []) << country_timezone + end end end end + + [primary_zones, secondary_zones].each do |zones| + zones.each_pair do |code, country_timezones| + country = @countries[code] + raise "Country not found: #{code}" if country.nil? + + country_timezones.each do |country_timezone| + country.add_zone(country_timezone) + end + end + end end # Writes a country index file. def write_countries_index dir = File.join(@output_dir, 'indexes') @@ -561,23 +574,21 @@ def create_file(output_dir) dir = File.join(output_dir, 'definitions', @path_elements.join(File::SEPARATOR)) FileUtils.mkdir_p(dir) open_file(File.join(output_dir, 'definitions', @name_elements.join(File::SEPARATOR)) + '.rb', 'w', :external_encoding => 'UTF-8', :universal_newline => true) do |file| + + file.instance_variable_set(:@tz_indent, 0) def file.indent(by) - if @tz_indent - @tz_indent += by - else - @tz_indent = by - end + @tz_indent += by end def file.puts(s) - super("#{' ' * (@tz_indent || 0)}#{s}") + super("#{' ' * @tz_indent}#{s}") end - + file.puts('# encoding: UTF-8') file.puts('') file.puts('# This file contains data derived from the IANA Time Zone Database') file.puts('# (http://www.iana.org/time-zones).') file.puts('') @@ -1070,11 +1081,11 @@ attr_reader :day_of_month attr_reader :day_of_week attr_reader :operator def initialize(spec) - raise "Invalid on: #{spec}" if spec !~ /^([0-9]+)|(last([A-z]+))|(([A-z]+)([<>]=)([0-9]+))$/ + raise "Invalid on: #{spec}" if spec !~ /^([0-9]+)|(last([A-Za-z]+))|(([A-Za-z]+)([<>]=)([0-9]+))$/ if $1 @type = :absolute @day_of_month = $1.to_i elsif $3 @@ -1179,10 +1190,10 @@ # substitution (%s) format or a fixed string. # # @private class TZDataFormat #:nodoc: def initialize(spec) - if spec =~ /([A-z]+)\/([A-z]+)/ + if spec =~ /([A-Z]+)\/([A-Z]+)/i @type = :alternate @standard_abbrev = $1 @daylight_abbrev = $2 elsif spec =~ /%s/ @type = :subst