class TZInfo::TZDataZone
:nodoc:
@private
A tz data Zone. Each line from the tz data is loaded as a TZDataObservance.
def add_observance(observance)
def add_observance(observance) @observances << observance end
def find_transitions
def find_transitions transitions = TZDataTransitions.new # algorithm from zic.c outzone start_time = nil until_time = nil @observances.each_with_index {|observance, i| std_offset = 0 use_start = i > 0 use_until = i < @observances.length - 1 utc_offset = observance.utc_offset start_zone_id = nil start_utc_offset = observance.utc_offset start_std_offset = 0 if observance.rule_set.count == 0 std_offset = observance.std_offset start_zone_id = observance.format.expand(utc_offset, std_offset, nil) if use_start transitions << TZDataTransition.new(start_time, utc_offset, std_offset, start_zone_id) use_start = false else # zic algorithm only outputs this if std_offset is non-zero # to get the initial LMT range, we output this regardless transitions << TZDataTransition.new(nil, utc_offset, std_offset, start_zone_id) end else (TZDataParser::MIN_YEAR..TZDataParser::MAX_YEAR).each {|year| if use_until && year > observance.valid_until.year break end activated_rules = [] observance.rule_set.each {|rule| activated_rule = rule.activate(year) activated_rules << activated_rule unless activated_rule.nil? } while true # turn until_time into UTC using the current utc_offset and std_offset until_time = observance.valid_until.to_utc(utc_offset, std_offset) if use_until earliest = nil activated_rules.each {|activated_rule| # recalculate the time using the current std_offset activated_rule.calculate_time(utc_offset, std_offset) earliest = activated_rule if earliest.nil? || activated_rule.at < earliest.at } break if earliest.nil? activated_rules.delete(earliest) break if use_until && earliest.at >= until_time std_offset = earliest.rule.save use_start = false if use_start && earliest.at == start_time if use_start if earliest.at < start_time start_utc_offset = observance.utc_offset start_std_offset = std_offset start_zone_id = observance.format.expand(start_utc_offset, earliest.rule.save, earliest.rule.letter) next end if start_zone_id.nil? && start_utc_offset + start_std_offset == observance.utc_offset + std_offset start_zone_id = observance.format.expand(start_utc_offset, earliest.rule.save, earliest.rule.letter) end end zone_id = observance.format.expand(observance.utc_offset, earliest.rule.save, earliest.rule.letter) transitions << TZDataTransition.new(earliest.at, observance.utc_offset, earliest.rule.save, zone_id) end } end if use_start start_zone_id = observance.format.expand(nil, nil, nil) if start_zone_id.nil? && observance.format.fixed? raise 'Could not determine time zone abbreviation to use just after until time' if start_zone_id.nil? transitions << TZDataTransition.new(start_time, start_utc_offset, start_std_offset, start_zone_id) end start_time = observance.valid_until.to_utc(utc_offset, std_offset) if use_until } transitions end
def initialize(name)
def initialize(name) super @observances = [] end
def write_index_record(file)
def write_index_record(file) file.puts(" timezone #{TZDataParser.quote_str(@name)}") end
def write_module(output_dir)
Writes the module for the zone. Iterates all the periods and asks them
def write_module(output_dir) puts "writing zone #{name}" create_file(output_dir) {|file| file.puts("timezone #{TZDataParser.quote_str(@name)} do |tz|") file.indent(2) transitions = find_transitions transitions.output_module(file) file.indent(-2) file.puts('end') } end