tzinfo 1.2.11 → 2.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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +3 -0
  4. data/CHANGES.md +469 -431
  5. data/LICENSE +13 -13
  6. data/README.md +368 -114
  7. data/lib/tzinfo/country.rb +131 -129
  8. data/lib/tzinfo/country_timezone.rb +70 -112
  9. data/lib/tzinfo/data_source.rb +389 -144
  10. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  11. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  12. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  13. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  14. data/lib/tzinfo/data_sources/ruby_data_source.rb +141 -0
  15. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  16. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  17. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +573 -0
  18. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +284 -0
  19. data/lib/tzinfo/data_sources.rb +8 -0
  20. data/lib/tzinfo/data_timezone.rb +33 -47
  21. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  22. data/lib/tzinfo/format1/country_definer.rb +17 -0
  23. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  24. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  25. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  26. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  27. data/lib/tzinfo/format1.rb +10 -0
  28. data/lib/tzinfo/format2/country_definer.rb +68 -0
  29. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  30. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  31. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  32. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  33. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  34. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  35. data/lib/tzinfo/format2.rb +10 -0
  36. data/lib/tzinfo/info_timezone.rb +26 -21
  37. data/lib/tzinfo/linked_timezone.rb +33 -52
  38. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  39. data/lib/tzinfo/string_deduper.rb +118 -0
  40. data/lib/tzinfo/time_with_offset.rb +128 -0
  41. data/lib/tzinfo/timestamp.rb +548 -0
  42. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  43. data/lib/tzinfo/timezone.rb +979 -502
  44. data/lib/tzinfo/timezone_offset.rb +84 -74
  45. data/lib/tzinfo/timezone_period.rb +151 -217
  46. data/lib/tzinfo/timezone_proxy.rb +70 -79
  47. data/lib/tzinfo/timezone_transition.rb +77 -109
  48. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  49. data/lib/tzinfo/version.rb +7 -0
  50. data/lib/tzinfo/with_offset.rb +61 -0
  51. data/lib/tzinfo.rb +60 -40
  52. data.tar.gz.sig +0 -0
  53. metadata +51 -115
  54. metadata.gz.sig +2 -3
  55. data/Rakefile +0 -107
  56. data/lib/tzinfo/annual_rules.rb +0 -51
  57. data/lib/tzinfo/country_index_definition.rb +0 -31
  58. data/lib/tzinfo/country_info.rb +0 -42
  59. data/lib/tzinfo/data_timezone_info.rb +0 -55
  60. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  61. data/lib/tzinfo/offset_rationals.rb +0 -77
  62. data/lib/tzinfo/posix_time_zone_parser.rb +0 -136
  63. data/lib/tzinfo/ruby_core_support.rb +0 -176
  64. data/lib/tzinfo/ruby_country_info.rb +0 -74
  65. data/lib/tzinfo/ruby_data_source.rb +0 -136
  66. data/lib/tzinfo/time_or_datetime.rb +0 -351
  67. data/lib/tzinfo/timezone_definition.rb +0 -36
  68. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  69. data/lib/tzinfo/timezone_info.rb +0 -30
  70. data/lib/tzinfo/timezone_transition_definition.rb +0 -104
  71. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  72. data/lib/tzinfo/transition_rule.rb +0 -325
  73. data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
  74. data/lib/tzinfo/zoneinfo_data_source.rb +0 -504
  75. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -516
  76. data/test/assets/payload.rb +0 -1
  77. data/test/tc_annual_rules.rb +0 -95
  78. data/test/tc_country.rb +0 -240
  79. data/test/tc_country_index_definition.rb +0 -69
  80. data/test/tc_country_info.rb +0 -16
  81. data/test/tc_country_timezone.rb +0 -173
  82. data/test/tc_data_source.rb +0 -218
  83. data/test/tc_data_timezone.rb +0 -99
  84. data/test/tc_data_timezone_info.rb +0 -18
  85. data/test/tc_info_timezone.rb +0 -34
  86. data/test/tc_linked_timezone.rb +0 -155
  87. data/test/tc_linked_timezone_info.rb +0 -23
  88. data/test/tc_offset_rationals.rb +0 -23
  89. data/test/tc_posix_time_zone_parser.rb +0 -261
  90. data/test/tc_ruby_core_support.rb +0 -168
  91. data/test/tc_ruby_country_info.rb +0 -110
  92. data/test/tc_ruby_data_source.rb +0 -175
  93. data/test/tc_time_or_datetime.rb +0 -674
  94. data/test/tc_timezone.rb +0 -1361
  95. data/test/tc_timezone_definition.rb +0 -113
  96. data/test/tc_timezone_index_definition.rb +0 -73
  97. data/test/tc_timezone_info.rb +0 -11
  98. data/test/tc_timezone_london.rb +0 -143
  99. data/test/tc_timezone_melbourne.rb +0 -142
  100. data/test/tc_timezone_new_york.rb +0 -142
  101. data/test/tc_timezone_offset.rb +0 -126
  102. data/test/tc_timezone_period.rb +0 -555
  103. data/test/tc_timezone_proxy.rb +0 -136
  104. data/test/tc_timezone_transition.rb +0 -366
  105. data/test/tc_timezone_transition_definition.rb +0 -295
  106. data/test/tc_timezone_utc.rb +0 -27
  107. data/test/tc_transition_data_timezone_info.rb +0 -433
  108. data/test/tc_transition_rule.rb +0 -663
  109. data/test/tc_zoneinfo_country_info.rb +0 -78
  110. data/test/tc_zoneinfo_data_source.rb +0 -1226
  111. data/test/tc_zoneinfo_timezone_info.rb +0 -2149
  112. data/test/test_utils.rb +0 -214
  113. data/test/ts_all.rb +0 -7
  114. data/test/ts_all_ruby.rb +0 -5
  115. data/test/ts_all_zoneinfo.rb +0 -9
  116. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  117. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -327
  118. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -230
  119. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  120. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  121. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  122. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  123. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -273
  124. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -198
  125. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -333
  126. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -277
  127. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -235
  128. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  129. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -940
  130. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -609
  131. data/test/tzinfo-data/tzinfo/data/version.rb +0 -20
  132. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  133. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  134. data/test/zoneinfo/America/New_York +0 -0
  135. data/test/zoneinfo/Australia/Melbourne +0 -0
  136. data/test/zoneinfo/EST +0 -0
  137. data/test/zoneinfo/Etc/UTC +0 -0
  138. data/test/zoneinfo/Europe/Amsterdam +0 -0
  139. data/test/zoneinfo/Europe/Andorra +0 -0
  140. data/test/zoneinfo/Europe/London +0 -0
  141. data/test/zoneinfo/Europe/Paris +0 -0
  142. data/test/zoneinfo/Europe/Prague +0 -0
  143. data/test/zoneinfo/Factory +0 -0
  144. data/test/zoneinfo/iso3166.tab +0 -274
  145. data/test/zoneinfo/leapseconds +0 -78
  146. data/test/zoneinfo/posix/Europe/London +0 -0
  147. data/test/zoneinfo/posixrules +0 -0
  148. data/test/zoneinfo/right/Europe/London +0 -0
  149. data/test/zoneinfo/zone.tab +0 -452
  150. data/test/zoneinfo/zone1970.tab +0 -384
  151. data/tzinfo.gemspec +0 -21
@@ -1,105 +1,96 @@
1
+ # encoding: UTF-8
2
+
1
3
  module TZInfo
2
4
 
3
- # A proxy class representing a timezone with a given identifier. TimezoneProxy
4
- # inherits from Timezone and can be treated like any Timezone loaded with
5
- # Timezone.get.
5
+ # A proxy class standing in for a {Timezone} with a given identifier.
6
+ # {TimezoneProxy} inherits from {Timezone} and can be treated identically to
7
+ # {Timezone} instances loaded with {Timezone.get}.
8
+ #
9
+ # {TimezoneProxy} instances are used to avoid the performance overhead of
10
+ # loading time zone data into memory, for example, by {Timezone.all}.
6
11
  #
7
- # The first time an attempt is made to access the data for the timezone, the
8
- # real Timezone is loaded. If the proxy's identifier was not valid, then an
9
- # exception will be raised at this point.
12
+ # The first time an attempt is made to access the data for the time zone, the
13
+ # real {Timezone} will be loaded is loaded. If the proxy's identifier was not
14
+ # valid, then an exception will be raised at this point.
10
15
  class TimezoneProxy < Timezone
11
- # Construct a new TimezoneProxy for the given identifier. The identifier
12
- # is not checked when constructing the proxy. It will be validated on the
13
- # when the real Timezone is loaded.
14
- def self.new(identifier)
15
- # Need to override new to undo the behaviour introduced in Timezone#new.
16
- tzp = super()
17
- tzp.send(:setup, identifier)
18
- tzp
16
+ # Initializes a new {TimezoneProxy}.
17
+ #
18
+ # The `identifier` parameter is not checked when initializing the proxy. It
19
+ # will be validated when the real {Timezone} instance is loaded.
20
+ #
21
+ # @param identifier [String] an IANA Time Zone Database time zone
22
+ # identifier.
23
+ def initialize(identifier)
24
+ super()
25
+ @identifier = identifier
26
+ @real_timezone = nil
19
27
  end
20
-
21
- # The identifier of the timezone, e.g. "Europe/Paris".
28
+
29
+ # (see Timezone#identifier)
22
30
  def identifier
23
31
  @real_timezone ? @real_timezone.identifier : @identifier
24
32
  end
25
-
26
- # Returns the TimezonePeriod for the given UTC time. utc can either be
27
- # a DateTime, Time or integer timestamp (Time.to_i). Any timezone
28
- # information in utc is ignored (it is treated as a UTC time).
29
- def period_for_utc(utc)
30
- real_timezone.period_for_utc(utc)
33
+
34
+ # (see Timezone#period_for)
35
+ def period_for(time)
36
+ real_timezone.period_for_utc(time)
31
37
  end
32
-
33
- # Returns the set of TimezonePeriod instances that are valid for the given
34
- # local time as an array. If you just want a single period, use
35
- # period_for_local instead and specify how abiguities should be resolved.
36
- # Returns an empty array if no periods are found for the given time.
37
- def periods_for_local(local)
38
- real_timezone.periods_for_local(local)
38
+
39
+ # (see Timezone#periods_for_local)
40
+ def periods_for_local(local_time)
41
+ real_timezone.periods_for_local(local_time)
39
42
  end
40
-
41
- # Returns an Array of TimezoneTransition instances representing the times
42
- # where the UTC offset of the timezone changes.
43
- #
44
- # Transitions are returned up to a given date and time up to a given date
45
- # and time (to).
46
- #
47
- # A from date and time may also be supplied using the from parameter. If
48
- # from is not nil, only transitions from that date and time onwards will be
49
- # returned.
50
- #
51
- # Comparisons with to are exclusive. Comparisons with from are inclusive.
52
- # If a transition falls precisely on to, it will be excluded. If a
53
- # transition falls on from, it will be included.
54
- #
55
- # Transitions returned are ordered by when they occur, from earliest to
56
- # latest.
57
- #
58
- # to and from can be specified using either a Time, DateTime, Time or
59
- # Timestamp.
60
- #
61
- # If from is specified and to is not greater than from, then an
62
- # ArgumentError exception is raised.
63
- #
64
- # ArgumentError is raised if to is nil or of either to or from are
65
- # Timestamps with unspecified offsets.
43
+
44
+ # (see Timezone#transitions_up_to)
66
45
  def transitions_up_to(to, from = nil)
67
46
  real_timezone.transitions_up_to(to, from)
68
47
  end
69
48
 
70
- # Returns the canonical zone for this Timezone.
49
+ # (see Timezone#canonical_zone)
71
50
  def canonical_zone
72
51
  real_timezone.canonical_zone
73
52
  end
74
-
75
- # Dumps this TimezoneProxy for marshalling.
53
+
54
+ # Returns a serialized representation of this {TimezoneProxy}. This method
55
+ # is called when using `Marshal.dump` with an instance of {TimezoneProxy}.
56
+ #
57
+ # @param limit [Integer] the maximum depth to dump - ignored. @return
58
+ # [String] a serialized representation of this {TimezoneProxy}.
59
+ # @return [String] a serialized representation of this {TimezoneProxy}.
76
60
  def _dump(limit)
77
61
  identifier
78
62
  end
79
-
80
- # Loads a marshalled TimezoneProxy.
63
+
64
+ # Loads a {TimezoneProxy} from the serialized representation returned by
65
+ # {_dump}. This is method is called when using `Marshal.load` or
66
+ # `Marshal.restore` to restore a serialized {Timezone}.
67
+ #
68
+ # @param data [String] a serialized representation of a {TimezoneProxy}.
69
+ # @return [TimezoneProxy] the result of converting `data` back into a
70
+ # {TimezoneProxy}.
81
71
  def self._load(data)
82
72
  TimezoneProxy.new(data)
83
73
  end
84
-
74
+
85
75
  private
86
- def setup(identifier)
87
- @identifier = identifier
88
- @real_timezone = nil
89
- end
90
-
91
- def real_timezone
92
- # Thread-safety: It is possible that the value of @real_timezone may be
93
- # calculated multiple times in concurrently executing threads. It is not
94
- # worth the overhead of locking to ensure that @real_timezone is only
95
- # calculated once.
96
- unless @real_timezone
97
- result = Timezone.get(@identifier)
98
- return result if frozen?
99
- @real_timezone = result
100
- end
101
76
 
102
- @real_timezone
103
- end
104
- end
77
+ # Returns the real {Timezone} instance being proxied.
78
+ #
79
+ # The real {Timezone} is loaded using {Timezone.get} on the first access.
80
+ #
81
+ # @return [Timezone] the real {Timezone} instance being proxied.
82
+ def real_timezone
83
+ # Thread-safety: It is possible that the value of @real_timezone may be
84
+ # calculated multiple times in concurrently executing threads. It is not
85
+ # worth the overhead of locking to ensure that @real_timezone is only
86
+ # calculated once.
87
+ unless @real_timezone
88
+ result = Timezone.get(@identifier)
89
+ return result if frozen?
90
+ @real_timezone = result
91
+ end
92
+
93
+ @real_timezone
94
+ end
95
+ end
105
96
  end
@@ -1,130 +1,98 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  module TZInfo
2
- # Represents a transition from one timezone offset to another at a particular
3
- # date and time.
5
+ # Represents a transition from one observed UTC offset ({TimezoneOffset} to
6
+ # another for a time zone.
4
7
  class TimezoneTransition
5
- # The offset this transition changes to (a TimezoneOffset instance).
8
+ # @return [TimezoneOffset] the offset this transition changes to.
6
9
  attr_reader :offset
7
-
8
- # The offset this transition changes from (a TimezoneOffset instance).
10
+
11
+ # @return [TimezoneOffset] the offset this transition changes from.
9
12
  attr_reader :previous_offset
10
-
11
- # Initializes a new TimezoneTransition.
13
+
14
+ # When this transition occurs as an `Integer` number of seconds since
15
+ # 1970-01-01 00:00:00 UTC ignoring leap seconds (i.e. each day is treated as
16
+ # if it were 86,400 seconds long). Equivalent to the result of calling the
17
+ # {Timestamp#value value} method on the {Timestamp} returned by {at}.
18
+ #
19
+ # @return [Integer] when this transition occurs as a number of seconds since
20
+ # 1970-01-01 00:00:00 UTC ignoring leap seconds.
21
+ attr_reader :timestamp_value
22
+
23
+ # Initializes a new {TimezoneTransition}.
24
+ #
25
+ # {TimezoneTransition} instances should not normally be constructed
26
+ # manually.
12
27
  #
13
- # TimezoneTransition instances should not normally be constructed manually.
14
- def initialize(offset, previous_offset)
28
+ # @param offset [TimezoneOffset] the offset the transition changes to.
29
+ # @param previous_offset [TimezoneOffset] the offset the transition changes
30
+ # from.
31
+ # @param timestamp_value [Integer] when the transition occurs as a
32
+ # number of seconds since 1970-01-01 00:00:00 UTC ignoring leap seconds
33
+ # (i.e. each day is treated as if it were 86,400 seconds long).
34
+ def initialize(offset, previous_offset, timestamp_value)
15
35
  @offset = offset
16
36
  @previous_offset = previous_offset
17
- @local_end_at = nil
18
- @local_start_at = nil
37
+ @timestamp_value = timestamp_value
19
38
  end
20
-
21
- # A TimeOrDateTime instance representing the UTC time when this transition
22
- # occurs.
39
+
40
+ # Returns a {Timestamp} instance representing the UTC time when this
41
+ # transition occurs.
42
+ #
43
+ # To obtain the result as a `Time` or `DateTime`, call either
44
+ # {Timestamp#to_time to_time} or {Timestamp#to_datetime to_datetime} on the
45
+ # {Timestamp} instance that is returned.
46
+ #
47
+ # @return [Timestamp] the UTC time when this transition occurs.
23
48
  def at
24
- raise_not_implemented('at')
25
- end
26
-
27
- # The UTC time when this transition occurs, returned as a DateTime instance.
28
- def datetime
29
- at.to_datetime
49
+ Timestamp.utc(@timestamp_value)
30
50
  end
31
-
32
- # The UTC time when this transition occurs, returned as a Time instance.
33
- def time
34
- at.to_time
35
- end
36
-
37
- # A TimeOrDateTime instance representing the local time when this transition
38
- # causes the previous observance to end (calculated from at using
39
- # previous_offset).
40
- def local_end_at
41
- # Thread-safety: It is possible that the value of @local_end_at may be
42
- # calculated multiple times in concurrently executing threads. It is not
43
- # worth the overhead of locking to ensure that @local_end_at is only
44
- # calculated once.
45
-
46
- unless @local_end_at
47
- result = at.add_with_convert(@previous_offset.utc_total_offset)
48
- return result if frozen?
49
- @local_end_at = result
50
- end
51
51
 
52
- @local_end_at
53
- end
54
-
55
- # The local time when this transition causes the previous observance to end,
56
- # returned as a DateTime instance.
57
- def local_end
58
- local_end_at.to_datetime
59
- end
60
-
61
- # The local time when this transition causes the previous observance to end,
62
- # returned as a Time instance.
63
- def local_end_time
64
- local_end_at.to_time
52
+ # Returns a {TimestampWithOffset} instance representing the local time when
53
+ # this transition causes the previous observance to end (calculated from
54
+ # {at} using {previous_offset}).
55
+ #
56
+ # To obtain the result as a `Time` or `DateTime`, call either
57
+ # {TimestampWithOffset#to_time to_time} or {TimestampWithOffset#to_datetime
58
+ # to_datetime} on the {TimestampWithOffset} instance that is returned.
59
+ #
60
+ # @return [TimestampWithOffset] the local time when this transition causes
61
+ # the previous observance to end.
62
+ def local_end_at
63
+ TimestampWithOffset.new(@timestamp_value, 0, @previous_offset.observed_utc_offset).set_timezone_offset(@previous_offset)
65
64
  end
66
-
67
- # A TimeOrDateTime instance representing the local time when this transition
68
- # causes the next observance to start (calculated from at using offset).
69
- def local_start_at
70
- # Thread-safety: It is possible that the value of @local_start_at may be
71
- # calculated multiple times in concurrently executing threads. It is not
72
- # worth the overhead of locking to ensure that @local_start_at is only
73
- # calculated once.
74
-
75
- unless @local_start_at
76
- result = at.add_with_convert(@offset.utc_total_offset)
77
- return result if frozen?
78
- @local_start_at = result
79
- end
80
65
 
81
- @local_start_at
82
- end
83
-
84
- # The local time when this transition causes the next observance to start,
85
- # returned as a DateTime instance.
86
- def local_start
87
- local_start_at.to_datetime
88
- end
89
-
90
- # The local time when this transition causes the next observance to start,
91
- # returned as a Time instance.
92
- def local_start_time
93
- local_start_at.to_time
66
+ # Returns a {TimestampWithOffset} instance representing the local time when
67
+ # this transition causes the next observance to start (calculated from {at}
68
+ # using {offset}).
69
+ #
70
+ # To obtain the result as a `Time` or `DateTime`, call either
71
+ # {TimestampWithOffset#to_time to_time} or {TimestampWithOffset#to_datetime
72
+ # to_datetime} on the {TimestampWithOffset} instance that is returned.
73
+ #
74
+ # @return [TimestampWithOffset] the local time when this transition causes
75
+ # the next observance to start.
76
+ def local_start_at
77
+ TimestampWithOffset.new(@timestamp_value, 0, @offset.observed_utc_offset).set_timezone_offset(@offset)
94
78
  end
95
-
96
- # Returns true if this TimezoneTransition is equal to the given
97
- # TimezoneTransition. Two TimezoneTransition instances are
98
- # considered to be equal by == if offset, previous_offset and at are all
99
- # equal.
79
+
80
+ # Determines if this {TimezoneTransition} is equal to another instance.
81
+ #
82
+ # @param tti [Object] the instance to test for equality.
83
+ # @return [Boolean] `true` if `tti` is a {TimezoneTransition} with the same
84
+ # {offset}, {previous_offset} and {timestamp_value} as this
85
+ # {TimezoneTransition}, otherwise `false`.
100
86
  def ==(tti)
101
87
  tti.kind_of?(TimezoneTransition) &&
102
- offset == tti.offset && previous_offset == tti.previous_offset && at == tti.at
103
- end
104
-
105
- # Returns true if this TimezoneTransition is equal to the given
106
- # TimezoneTransition. Two TimezoneTransition instances are
107
- # considered to be equal by eql? if offset, previous_offset and at are all
108
- # equal and the type used to define at in both instances is the same.
109
- def eql?(tti)
110
- tti.kind_of?(TimezoneTransition) &&
111
- offset == tti.offset && previous_offset == tti.previous_offset && at.eql?(tti.at)
112
- end
113
-
114
- # Returns a hash of this TimezoneTransition instance.
115
- def hash
116
- @offset.hash ^ @previous_offset.hash ^ at.hash
117
- end
118
-
119
- # Returns internal object state as a programmer-readable string.
120
- def inspect
121
- "#<#{self.class}: #{at.inspect},#{@offset.inspect}>"
88
+ offset == tti.offset && previous_offset == tti.previous_offset && timestamp_value == tti.timestamp_value
122
89
  end
90
+ alias eql? ==
123
91
 
124
- private
125
-
126
- def raise_not_implemented(method_name)
127
- raise NotImplementedError, "Subclasses must override #{method_name}"
92
+ # @return [Integer] a hash based on {offset}, {previous_offset} and
93
+ # {timestamp_value}.
94
+ def hash
95
+ [@offset, @previous_offset, @timestamp_value].hash
128
96
  end
129
97
  end
130
98
  end
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ # Represents a period of time in a time zone where the same offset from UTC
6
+ # applies. The period of time is bounded at at least one end, either having a
7
+ # start transition, end transition or both start and end transitions.
8
+ class TransitionsTimezonePeriod < TimezonePeriod
9
+ # @return [TimezoneTransition] the transition that defines the start of this
10
+ # {TimezonePeriod} (`nil` if the start is unbounded).
11
+ attr_reader :start_transition
12
+
13
+ # @return [TimezoneTransition] the transition that defines the end of this
14
+ # {TimezonePeriod} (`nil` if the end is unbounded).
15
+ attr_reader :end_transition
16
+
17
+ # Initializes a {TransitionsTimezonePeriod}.
18
+ #
19
+ # At least one of `start_transition` and `end_transition` must be specified.
20
+ #
21
+ # @param start_transition [TimezoneTransition] the transition that defines
22
+ # the start of the period, or `nil` if the start is unbounded.
23
+ # @param end_transition [TimezoneTransition] the transition that defines the
24
+ # end of the period, or `nil` if the end is unbounded.
25
+ # @raise [ArgumentError] if both `start_transition` and `end_transition` are
26
+ # `nil`.
27
+ def initialize(start_transition, end_transition)
28
+ if start_transition
29
+ super(start_transition.offset)
30
+ elsif end_transition
31
+ super(end_transition.previous_offset)
32
+ else
33
+ raise ArgumentError, 'At least one of start_transition and end_transition must be specified'
34
+ end
35
+
36
+ @start_transition = start_transition
37
+ @end_transition = end_transition
38
+ end
39
+
40
+ # Determines if this {TransitionsTimezonePeriod} is equal to another
41
+ # instance.
42
+ #
43
+ # @param p [Object] the instance to test for equality.
44
+ # @return [Boolean] `true` if `p` is a {TransitionsTimezonePeriod} with the
45
+ # same {offset}, {start_transition} and {end_transition}, otherwise
46
+ # `false`.
47
+ def ==(p)
48
+ p.kind_of?(TransitionsTimezonePeriod) && start_transition == p.start_transition && end_transition == p.end_transition
49
+ end
50
+ alias eql? ==
51
+
52
+ # @return [Integer] a hash based on {start_transition} and {end_transition}.
53
+ def hash
54
+ [@start_transition, @end_transition].hash
55
+ end
56
+
57
+ # @return [String] the internal object state as a programmer-readable
58
+ # `String`.
59
+ def inspect
60
+ "#<#{self.class}: @start_transition=#{@start_transition.inspect}, @end_transition=#{@end_transition.inspect}>"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ # The TZInfo version number.
6
+ VERSION = '2.0.0'
7
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ # The {WithOffset} module is included in {TimeWithOffset},
6
+ # {DateTimeWithOffset} and {TimestampWithOffset}. It provides an override for
7
+ # the {strftime} method that handles expanding the `%Z` directive according to
8
+ # the {TimezoneOffset#abbreviation abbreviation} of the {TimezoneOffset}
9
+ # associated with a local time.
10
+ module WithOffset
11
+ # Overrides the `Time`, `DateTime` or {Timestamp} version of `strftime`,
12
+ # replacing `%Z` with the {TimezoneOffset#abbreviation abbreviation} of the
13
+ # associated {TimezoneOffset}. If there is no associated offset, `%Z` is
14
+ # expanded by the base class instead.
15
+ #
16
+ # All the format directives handled by the base class are supported.
17
+ #
18
+ # @param format [String] the format string.
19
+ # @return [String] the formatted time.
20
+ # @raise [ArgumentError] if `format` is `nil`.
21
+ def strftime(format)
22
+ raise ArgumentError, 'format must be specified' unless format
23
+
24
+ if_timezone_offset do |o|
25
+ abbreviation = nil
26
+
27
+ format = format.gsub(/%(%*)Z/) do
28
+ if $1.length.odd?
29
+ # Return %%Z so the real strftime treats it as a literal %Z too.
30
+ "#$1%Z"
31
+ else
32
+ "#$1#{abbreviation ||= o.abbreviation.gsub(/%/, '%%')}"
33
+ end
34
+ end
35
+ end
36
+
37
+ super
38
+ end
39
+
40
+ protected
41
+
42
+ # Performs a calculation if there is an associated {TimezoneOffset}.
43
+ #
44
+ # @param result [Object] a result value that can be manipulated by the block
45
+ # if there is an associated {TimezoneOffset}.
46
+ # @yield [period, result] if there is an associated {TimezoneOffset}, the
47
+ # block is yielded to in order to calculate the method result.
48
+ # @yieldparam period [TimezoneOffset] the associated {TimezoneOffset}.
49
+ # @yieldparam result [Object] the `result` parameter.
50
+ # @yieldreturn [Object] the result of the calculation performed if there is
51
+ # an associated {TimezoneOffset}.
52
+ # @return [Object] the result of the block if there is an associated
53
+ # {TimezoneOffset}, otherwise the `result` parameter.
54
+ #
55
+ # @private
56
+ def if_timezone_offset(result = nil) #:nodoc:
57
+ to = timezone_offset
58
+ to ? yield(to, result) : result
59
+ end
60
+ end
61
+ end
data/lib/tzinfo.rb CHANGED
@@ -1,43 +1,63 @@
1
- # Top level module for TZInfo.
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # The top level module for TZInfo.
2
5
  module TZInfo
3
6
  end
4
7
 
5
- require 'tzinfo/ruby_core_support'
6
- require 'tzinfo/offset_rationals'
7
- require 'tzinfo/time_or_datetime'
8
-
9
- require 'tzinfo/timezone_definition'
10
-
11
- require 'tzinfo/timezone_offset'
12
- require 'tzinfo/timezone_transition'
13
- require 'tzinfo/transition_rule'
14
- require 'tzinfo/annual_rules'
15
- require 'tzinfo/timezone_transition_definition'
16
-
17
- require 'tzinfo/timezone_index_definition'
18
-
19
- require 'tzinfo/timezone_info'
20
- require 'tzinfo/data_timezone_info'
21
- require 'tzinfo/linked_timezone_info'
22
- require 'tzinfo/transition_data_timezone_info'
23
- require 'tzinfo/zoneinfo_timezone_info'
24
-
25
- require 'tzinfo/data_source'
26
- require 'tzinfo/ruby_data_source'
27
- require 'tzinfo/posix_time_zone_parser'
28
- require 'tzinfo/zoneinfo_data_source'
29
-
30
- require 'tzinfo/timezone_period'
31
- require 'tzinfo/timezone'
32
- require 'tzinfo/info_timezone'
33
- require 'tzinfo/data_timezone'
34
- require 'tzinfo/linked_timezone'
35
- require 'tzinfo/timezone_proxy'
36
-
37
- require 'tzinfo/country_index_definition'
38
- require 'tzinfo/country_info'
39
- require 'tzinfo/ruby_country_info'
40
- require 'tzinfo/zoneinfo_country_info'
41
-
42
- require 'tzinfo/country'
43
- require 'tzinfo/country_timezone'
8
+ require_relative 'tzinfo/version'
9
+
10
+ require_relative 'tzinfo/string_deduper'
11
+
12
+ require_relative 'tzinfo/timestamp'
13
+
14
+ require_relative 'tzinfo/with_offset'
15
+ require_relative 'tzinfo/datetime_with_offset'
16
+ require_relative 'tzinfo/time_with_offset'
17
+ require_relative 'tzinfo/timestamp_with_offset'
18
+
19
+ require_relative 'tzinfo/timezone_offset'
20
+ require_relative 'tzinfo/timezone_transition'
21
+
22
+ require_relative 'tzinfo/data_sources'
23
+ require_relative 'tzinfo/data_sources/timezone_info'
24
+ require_relative 'tzinfo/data_sources/data_timezone_info'
25
+ require_relative 'tzinfo/data_sources/linked_timezone_info'
26
+ require_relative 'tzinfo/data_sources/constant_offset_data_timezone_info'
27
+ require_relative 'tzinfo/data_sources/transitions_data_timezone_info'
28
+
29
+ require_relative 'tzinfo/data_sources/country_info'
30
+
31
+ require_relative 'tzinfo/data_sources/zoneinfo_reader'
32
+
33
+ require_relative 'tzinfo/data_source'
34
+ require_relative 'tzinfo/data_sources/ruby_data_source'
35
+ require_relative 'tzinfo/data_sources/zoneinfo_data_source'
36
+
37
+ require_relative 'tzinfo/timezone_period'
38
+ require_relative 'tzinfo/offset_timezone_period'
39
+ require_relative 'tzinfo/transitions_timezone_period'
40
+ require_relative 'tzinfo/timezone'
41
+ require_relative 'tzinfo/info_timezone'
42
+ require_relative 'tzinfo/data_timezone'
43
+ require_relative 'tzinfo/linked_timezone'
44
+ require_relative 'tzinfo/timezone_proxy'
45
+
46
+ require_relative 'tzinfo/country'
47
+ require_relative 'tzinfo/country_timezone'
48
+
49
+ require_relative 'tzinfo/format2'
50
+ require_relative 'tzinfo/format2/country_definer'
51
+ require_relative 'tzinfo/format2/country_index_definer'
52
+ require_relative 'tzinfo/format2/country_index_definition'
53
+ require_relative 'tzinfo/format2/timezone_definer'
54
+ require_relative 'tzinfo/format2/timezone_definition'
55
+ require_relative 'tzinfo/format2/timezone_index_definer'
56
+ require_relative 'tzinfo/format2/timezone_index_definition'
57
+
58
+ require_relative 'tzinfo/format1'
59
+ require_relative 'tzinfo/format1/country_definer'
60
+ require_relative 'tzinfo/format1/country_index_definition'
61
+ require_relative 'tzinfo/format1/timezone_definer'
62
+ require_relative 'tzinfo/format1/timezone_definition'
63
+ require_relative 'tzinfo/format1/timezone_index_definition'
data.tar.gz.sig CHANGED
Binary file