Class: TZInfo::DataSources::TransitionsDataTimezoneInfo

Inherits:
DataTimezoneInfo show all
Defined in:
lib/tzinfo/data_sources/transitions_data_timezone_info.rb

Overview

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

Instance Attribute Summary collapse

Attributes inherited from TimezoneInfo

#identifier

Instance Method Summary collapse

Methods inherited from DataTimezoneInfo

#create_timezone

Methods inherited from TimezoneInfo

#create_timezone, #inspect

Constructor Details

#initialize(identifier, transitions) ⇒ TransitionsDataTimezoneInfo

Initializes a new TZInfo::DataSources::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 timestamp_value that is greater than the timestamp_value of the prior transition.

Parameters:

  • identifier (String)

    the identifier of the time zone.

  • transitions (Array<TimezoneTransitions>)

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

Raises:

  • (ArgumentError)

    if identifier is nil.

  • (ArgumentError)

    if transitions is nil.

  • (ArgumentError)

    if transitions is an empty Array.


31
32
33
34
35
36
# 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

Instance Attribute Details

#transitionsArray<TimezoneTransition> (readonly)

Returns the transitions that define this time zone in order of ascending timestamp.

Returns:

  • (Array<TimezoneTransition>)

    the transitions that define this time zone in order of ascending timestamp.


11
12
13
# File 'lib/tzinfo/data_sources/transitions_data_timezone_info.rb', line 11

def transitions
  @transitions
end

Instance Method Details

#period_for(timestamp) ⇒ TimezonePeriod

Returns the TimezonePeriod observed at the time specified by timestamp.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    may be raised if timestamp is nil or does not have a specified utc_offset.


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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

#periods_for_local(local_timestamp) ⇒ Array<TimezonePeriod>

Returns an Array containing the TimezonePeriods that could be observed at the local time specified by local_timestamp. The results are are ordered by increasing UTC start date. An empty Array is returned if no periods are found for the given local time.

Parameters:

Returns:

Raises:

  • (ArgumentError)

    may be raised if local_timestamp is nil, or has a specified utc_offset.


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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

#transitions_up_to(to_timestamp, from_timestamp = nil) ⇒ Array<TimezoneTransition>

Returns an Array of TimezoneTransition instances representing the times where the UTC offset of the time zone changes.

Transitions are returned up to a given Timestamp (to_timestamp).

A from Timestamp may also be supplied using the from_timestamp parameter. If from_timestamp is specified, only transitions from that time onwards will be returned.

Comparisons with to_timestamp are exclusive. Comparisons with from_timestamp are inclusive. If a transition falls precisely on to_timestamp, it will be excluded. If a transition falls on from_timestamp, it will be included.

Transitions returned are ordered by when they occur, from earliest to latest.

Parameters:

  • to_timestamp (Timestamp)

    a Timestamp with a specified utc_offset. Transitions are returned if they occur before this time.

  • from_timestamp (Timestamp) (defaults to: nil)

    an optional Timestamp with a specified utc_offset. If specified, transitions are returned if they occur at or after this time.

Returns:

Raises:

  • (ArgumentError)

    may be raised if to_timestamp is nil or does not have a specified utc_offset.

  • (ArgumentError)

    may be raised if from_timestamp is specified but does not have a specified utc_offset.

  • (ArgumentError)

    may be raised if from_timestamp is specified but is not earlier than or at the same time as to_timestamp.


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# 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