class TZInfo::DataSources::TransitionsDataTimezoneInfo

Represents a data time zone defined by a list of transitions that change the locally observed time.

Attributes

@return [Array<TimezoneTransition>] the transitions that define this

time zone in order of ascending timestamp.

Public Class Methods

Initializes a new {TransitionsDataTimezoneInfo}.

The passed in ‘identifier` instance will be frozen. A reference to the passed in `Array` will be retained.

The ‘transitions` `Array` must be sorted in order of ascending timestamp. Each transition must have a {TimezoneTransition#timestamp_value timestamp_value} that is greater than the {TimezoneTransition#timestamp_value timestamp_value} of the prior transition.

@param identifier [String] the identifier of the time zone. @param transitions [Array<TimezoneTransitions>] an ‘Array` of

transitions that each indicate when a change occurs in the locally
observed time.

@raise [ArgumentError] if ‘identifier` is `nil`. @raise [ArgumentError] if `transitions` is `nil`. @raise [ArgumentError] if `transitions` is an empty `Array`.

Calls superclass method
# File lib/tzinfo/data_sources/transitions_data_timezone_info.rb, line 31
def initialize(identifier, transitions)
  super(identifier)
  raise ArgumentError, 'transitions must be specified' unless transitions
  raise ArgumentError, 'transitions must not be an empty Array' if transitions.empty?
  @transitions = transitions.freeze
end

Public Instance Methods

(see DataTimezoneInfo#period_for)

# File lib/tzinfo/data_sources/transitions_data_timezone_info.rb, line 39
def period_for(timestamp)
  raise ArgumentError, 'timestamp must be specified' unless timestamp
  raise ArgumentError, 'timestamp must have a specified utc_offset' unless timestamp.utc_offset

  timestamp_value = timestamp.value

  index = find_minimum_transition {|t| t.timestamp_value >= timestamp_value }

  if index
    transition = @transitions[index]

    if transition.timestamp_value == timestamp_value
      # timestamp occurs within the second of the found transition, so is
      # the transition that starts the period.
      start_transition = transition
      end_transition = @transitions[index + 1]
    else
      # timestamp occurs before the second of the found transition, so is
      # the transition that ends the period.
      start_transition = index == 0 ? nil : @transitions[index - 1]
      end_transition = transition
    end
  else
    start_transition = @transitions.last
    end_transition = nil
  end

  TransitionsTimezonePeriod.new(start_transition, end_transition)
end

(see DataTimezoneInfo#periods_for_local)

# File lib/tzinfo/data_sources/transitions_data_timezone_info.rb, line 70
def periods_for_local(local_timestamp)
  raise ArgumentError, 'local_timestamp must be specified' unless local_timestamp
  raise ArgumentError, 'local_timestamp must have an unspecified utc_offset' if local_timestamp.utc_offset

  local_timestamp_value = local_timestamp.value
  latest_possible_utc_value = local_timestamp_value + 86400
  earliest_possible_utc_value = local_timestamp_value - 86400

  # Find the index of the first transition that occurs after a latest
  # possible UTC representation of the local timestamp and then search
  # backwards until an earliest possible UTC representation.

  index = find_minimum_transition {|t| t.timestamp_value >= latest_possible_utc_value }

  # No transitions after latest_possible_utc_value, set to max index + 1
  # to search backwards including the period after the last transition
  index = @transitions.length unless index

  result = []

  index.downto(0) do |i|
    start_transition = i > 0 ? @transitions[i - 1] : nil
    end_transition = @transitions[i]
    offset = start_transition ? start_transition.offset : end_transition.previous_offset
    utc_timestamp_value = local_timestamp_value - offset.observed_utc_offset

    # It is not necessary to compare the sub-seconds because a timestamp
    # is in the period if is >= the start transition (sub-seconds would
    # make == become >) and if it is < the end transition (which
    # sub-seconds cannot affect).
    if (!start_transition || utc_timestamp_value >= start_transition.timestamp_value) && (!end_transition || utc_timestamp_value < end_transition.timestamp_value)
      result << TransitionsTimezonePeriod.new(start_transition, end_transition)
    elsif end_transition && end_transition.timestamp_value < earliest_possible_utc_value
      break
    end
  end

  result.reverse!
end

(see DataTimezoneInfo#transitions_up_to)

# File lib/tzinfo/data_sources/transitions_data_timezone_info.rb, line 111
def transitions_up_to(to_timestamp, from_timestamp = nil)
  raise ArgumentError, 'to_timestamp must be specified' unless to_timestamp
  raise ArgumentError, 'to_timestamp must have a specified utc_offset' unless to_timestamp.utc_offset

  if from_timestamp
    raise ArgumentError, 'from_timestamp must have a specified utc_offset' unless from_timestamp.utc_offset
    raise ArgumentError, 'to_timestamp must be greater than from_timestamp' if to_timestamp <= from_timestamp
  end

  if from_timestamp
    from_index = find_minimum_transition {|t| transition_on_or_after_timestamp?(t, from_timestamp) }
    return [] unless from_index
  else
    from_index = 0
  end

  to_index = find_minimum_transition {|t| transition_on_or_after_timestamp?(t, to_timestamp) }

  if to_index
    return [] if to_index < 1
    to_index -= 1
  else
    to_index = -1
  end

  @transitions[from_index..to_index]
end