tzinfo 1.2.1 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +3 -0
  4. data/CHANGES.md +693 -315
  5. data/LICENSE +13 -13
  6. data/README.md +368 -113
  7. data/lib/tzinfo/annual_rules.rb +71 -0
  8. data/lib/tzinfo/country.rb +148 -120
  9. data/lib/tzinfo/country_timezone.rb +71 -101
  10. data/lib/tzinfo/data_source.rb +400 -144
  11. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  12. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  13. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  14. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  15. data/lib/tzinfo/data_sources/posix_time_zone_parser.rb +181 -0
  16. data/lib/tzinfo/data_sources/ruby_data_source.rb +145 -0
  17. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  18. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  19. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +596 -0
  20. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +486 -0
  21. data/lib/tzinfo/data_sources.rb +8 -0
  22. data/lib/tzinfo/data_timezone.rb +33 -47
  23. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  24. data/lib/tzinfo/format1/country_definer.rb +17 -0
  25. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  26. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  27. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  28. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  29. data/lib/tzinfo/format1.rb +10 -0
  30. data/lib/tzinfo/format2/country_definer.rb +68 -0
  31. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  32. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  33. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  34. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  35. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  36. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  37. data/lib/tzinfo/format2.rb +10 -0
  38. data/lib/tzinfo/info_timezone.rb +26 -21
  39. data/lib/tzinfo/linked_timezone.rb +33 -52
  40. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  41. data/lib/tzinfo/string_deduper.rb +118 -0
  42. data/lib/tzinfo/time_with_offset.rb +154 -0
  43. data/lib/tzinfo/timestamp.rb +552 -0
  44. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  45. data/lib/tzinfo/timezone.rb +997 -473
  46. data/lib/tzinfo/timezone_offset.rb +91 -54
  47. data/lib/tzinfo/timezone_period.rb +163 -188
  48. data/lib/tzinfo/timezone_proxy.rb +75 -49
  49. data/lib/tzinfo/timezone_transition.rb +77 -99
  50. data/lib/tzinfo/transition_rule.rb +455 -0
  51. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  52. data/lib/tzinfo/untaint_ext.rb +18 -0
  53. data/lib/tzinfo/version.rb +7 -0
  54. data/lib/tzinfo/with_offset.rb +61 -0
  55. data/lib/tzinfo.rb +74 -29
  56. data.tar.gz.sig +0 -0
  57. metadata +72 -120
  58. metadata.gz.sig +0 -0
  59. data/Rakefile +0 -104
  60. data/lib/tzinfo/country_index_definition.rb +0 -31
  61. data/lib/tzinfo/country_info.rb +0 -42
  62. data/lib/tzinfo/data_timezone_info.rb +0 -55
  63. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  64. data/lib/tzinfo/offset_rationals.rb +0 -77
  65. data/lib/tzinfo/ruby_core_support.rb +0 -146
  66. data/lib/tzinfo/ruby_country_info.rb +0 -70
  67. data/lib/tzinfo/ruby_data_source.rb +0 -136
  68. data/lib/tzinfo/time_or_datetime.rb +0 -333
  69. data/lib/tzinfo/timezone_definition.rb +0 -36
  70. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  71. data/lib/tzinfo/timezone_info.rb +0 -30
  72. data/lib/tzinfo/timezone_transition_definition.rb +0 -101
  73. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  74. data/lib/tzinfo/zoneinfo_country_info.rb +0 -35
  75. data/lib/tzinfo/zoneinfo_data_source.rb +0 -460
  76. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -245
  77. data/test/tc_country.rb +0 -236
  78. data/test/tc_country_index_definition.rb +0 -69
  79. data/test/tc_country_info.rb +0 -16
  80. data/test/tc_country_timezone.rb +0 -161
  81. data/test/tc_data_source.rb +0 -192
  82. data/test/tc_data_timezone.rb +0 -99
  83. data/test/tc_data_timezone_info.rb +0 -18
  84. data/test/tc_info_timezone.rb +0 -34
  85. data/test/tc_linked_timezone.rb +0 -155
  86. data/test/tc_linked_timezone_info.rb +0 -23
  87. data/test/tc_offset_rationals.rb +0 -23
  88. data/test/tc_ruby_core_support.rb +0 -168
  89. data/test/tc_ruby_country_info.rb +0 -80
  90. data/test/tc_ruby_data_source.rb +0 -143
  91. data/test/tc_time_or_datetime.rb +0 -639
  92. data/test/tc_timezone.rb +0 -1334
  93. data/test/tc_timezone_definition.rb +0 -113
  94. data/test/tc_timezone_index_definition.rb +0 -73
  95. data/test/tc_timezone_info.rb +0 -11
  96. data/test/tc_timezone_london.rb +0 -143
  97. data/test/tc_timezone_melbourne.rb +0 -142
  98. data/test/tc_timezone_new_york.rb +0 -142
  99. data/test/tc_timezone_offset.rb +0 -126
  100. data/test/tc_timezone_period.rb +0 -548
  101. data/test/tc_timezone_proxy.rb +0 -113
  102. data/test/tc_timezone_transition.rb +0 -352
  103. data/test/tc_timezone_transition_definition.rb +0 -284
  104. data/test/tc_timezone_utc.rb +0 -27
  105. data/test/tc_transition_data_timezone_info.rb +0 -423
  106. data/test/tc_zoneinfo_country_info.rb +0 -64
  107. data/test/tc_zoneinfo_data_source.rb +0 -985
  108. data/test/tc_zoneinfo_timezone_info.rb +0 -814
  109. data/test/test_utils.rb +0 -132
  110. data/test/ts_all.rb +0 -7
  111. data/test/ts_all_ruby.rb +0 -5
  112. data/test/ts_all_zoneinfo.rb +0 -7
  113. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  114. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -315
  115. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -218
  116. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  117. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  118. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  119. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  120. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -261
  121. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -186
  122. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -321
  123. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -265
  124. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -220
  125. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  126. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -927
  127. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -594
  128. data/test/tzinfo-data/tzinfo/data/version.rb +0 -14
  129. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  130. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  131. data/test/zoneinfo/America/New_York +0 -0
  132. data/test/zoneinfo/Australia/Melbourne +0 -0
  133. data/test/zoneinfo/EST +0 -0
  134. data/test/zoneinfo/Etc/UTC +0 -0
  135. data/test/zoneinfo/Europe/Amsterdam +0 -0
  136. data/test/zoneinfo/Europe/Andorra +0 -0
  137. data/test/zoneinfo/Europe/London +0 -0
  138. data/test/zoneinfo/Europe/Paris +0 -0
  139. data/test/zoneinfo/Europe/Prague +0 -0
  140. data/test/zoneinfo/Factory +0 -0
  141. data/test/zoneinfo/iso3166.tab +0 -275
  142. data/test/zoneinfo/posix/Europe/London +0 -0
  143. data/test/zoneinfo/posixrules +0 -0
  144. data/test/zoneinfo/right/Europe/London +0 -0
  145. data/test/zoneinfo/zone.tab +0 -452
  146. data/tzinfo.gemspec +0 -21
@@ -1,74 +1,111 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  module TZInfo
2
- # Represents an offset defined in a Timezone data file.
5
+ # Represents an offset from UTC observed by a time zone.
3
6
  class TimezoneOffset
4
- # The base offset of the timezone from UTC in seconds.
5
- attr_reader :utc_offset
6
-
7
- # The offset from standard time for the zone in seconds (i.e. non-zero if
8
- # daylight savings is being observed).
7
+ # Returns the base offset from UTC in seconds (`observed_utc_offset -
8
+ # std_offset`). This does not include any adjustment made for daylight
9
+ # savings time and will typically remain constant throughout the year.
10
+ #
11
+ # To obtain the currently observed offset from UTC, including the effect of
12
+ # daylight savings time, use {observed_utc_offset} instead.
13
+ #
14
+ # If you require accurate {base_utc_offset} values, you should install the
15
+ # tzinfo-data gem and set {DataSources::RubyDataSource} as the {DataSource}.
16
+ # When using {DataSources::ZoneinfoDataSource}, the value of
17
+ # {base_utc_offset} has to be derived from changes to the observed UTC
18
+ # offset and DST status since it is not included in zoneinfo files.
19
+ #
20
+ # @return [Integer] the base offset from UTC in seconds.
21
+ attr_reader :base_utc_offset
22
+ alias utc_offset base_utc_offset
23
+
24
+ # Returns the offset from the time zone's standard time in seconds
25
+ # (`observed_utc_offset - base_utc_offset`). Zero when daylight savings time
26
+ # is not in effect. Non-zero (usually 3600 = 1 hour) if daylight savings is
27
+ # being observed.
28
+ #
29
+ # If you require accurate {std_offset} values, you should install the
30
+ # tzinfo-data gem and set {DataSources::RubyDataSource} as the {DataSource}.
31
+ # When using {DataSources::ZoneinfoDataSource}, the value of {std_offset}
32
+ # has to be derived from changes to the observed UTC offset and DST status
33
+ # since it is not included in zoneinfo files.
34
+ #
35
+ # @return [Integer] the offset from the time zone's standard time in
36
+ # seconds.
9
37
  attr_reader :std_offset
10
-
11
- # The total offset of this observance from UTC in seconds
12
- # (utc_offset + std_offset).
13
- attr_reader :utc_total_offset
14
-
15
- # The abbreviation that identifies this observance, e.g. "GMT"
16
- # (Greenwich Mean Time) or "BST" (British Summer Time) for "Europe/London". The returned identifier is a
17
- # symbol.
38
+
39
+ # Returns the observed offset from UTC in seconds (`base_utc_offset +
40
+ # std_offset`). This includes adjustments made for daylight savings time.
41
+ #
42
+ # @return [Integer] the observed offset from UTC in seconds.
43
+ attr_reader :observed_utc_offset
44
+ alias utc_total_offset observed_utc_offset
45
+
46
+ # The abbreviation that identifies this offset. For example GMT
47
+ # (Greenwich Mean Time) or BST (British Summer Time) for Europe/London.
48
+ #
49
+ # @return [String] the abbreviation that identifies this offset.
18
50
  attr_reader :abbreviation
19
-
20
- # Constructs a new TimezoneOffset. utc_offset and std_offset are specified
21
- # in seconds.
22
- def initialize(utc_offset, std_offset, abbreviation)
23
- @utc_offset = utc_offset
24
- @std_offset = std_offset
25
- @abbreviation = abbreviation
26
-
27
- @utc_total_offset = @utc_offset + @std_offset
51
+ alias abbr abbreviation
52
+
53
+ # Initializes a new {TimezoneOffset}.
54
+ #
55
+ # {TimezoneOffset} instances should not normally be constructed manually.
56
+ #
57
+ # The passed in `abbreviation` instance will be frozen.
58
+ #
59
+ # @param base_utc_offset [Integer] the base offset from UTC in seconds.
60
+ # @param std_offset [Integer] the offset from standard time in seconds.
61
+ # @param abbreviation [String] the abbreviation identifying the offset.
62
+ def initialize(base_utc_offset, std_offset, abbreviation)
63
+ @base_utc_offset = base_utc_offset
64
+ @std_offset = std_offset
65
+ @abbreviation = abbreviation.freeze
66
+
67
+ @observed_utc_offset = @base_utc_offset + @std_offset
28
68
  end
29
-
30
- # True if std_offset is non-zero.
69
+
70
+ # Determines if daylight savings is in effect (i.e. if {std_offset} is
71
+ # non-zero).
72
+ #
73
+ # @return [Boolean] `true` if {std_offset} is non-zero, otherwise `false`.
31
74
  def dst?
32
75
  @std_offset != 0
33
76
  end
34
-
35
- # Converts a UTC Time, DateTime or integer timestamp to local time, based on
36
- # the offset of this period.
37
- def to_local(utc)
38
- TimeOrDateTime.wrap(utc) {|wrapped|
39
- wrapped + @utc_total_offset
40
- }
41
- end
42
-
43
- # Converts a local Time, DateTime or integer timestamp to UTC, based on the
44
- # offset of this period.
45
- def to_utc(local)
46
- TimeOrDateTime.wrap(local) {|wrapped|
47
- wrapped - @utc_total_offset
48
- }
49
- end
50
-
51
- # Returns true if and only if toi has the same utc_offset, std_offset
52
- # and abbreviation as this TimezoneOffset.
77
+
78
+ # Determines if this {TimezoneOffset} is equal to another instance.
79
+ #
80
+ # @param toi [Object] the instance to test for equality.
81
+ # @return [Boolean] `true` if `toi` is a {TimezoneOffset} with the same
82
+ # {utc_offset}, {std_offset} and {abbreviation} as this {TimezoneOffset},
83
+ # otherwise `false`.
53
84
  def ==(toi)
54
85
  toi.kind_of?(TimezoneOffset) &&
55
- utc_offset == toi.utc_offset && std_offset == toi.std_offset && abbreviation == toi.abbreviation
86
+ base_utc_offset == toi.base_utc_offset && std_offset == toi.std_offset && abbreviation == toi.abbreviation
56
87
  end
57
-
58
- # Returns true if and only if toi has the same utc_offset, std_offset
59
- # and abbreviation as this TimezoneOffset.
88
+
89
+ # Determines if this {TimezoneOffset} is equal to another instance.
90
+ #
91
+ # @param toi [Object] the instance to test for equality.
92
+ # @return [Boolean] `true` if `toi` is a {TimezoneOffset} with the same
93
+ # {utc_offset}, {std_offset} and {abbreviation} as this {TimezoneOffset},
94
+ # otherwise `false`.
60
95
  def eql?(toi)
61
96
  self == toi
62
97
  end
63
-
64
- # Returns a hash of this TimezoneOffset.
98
+
99
+ # @return [Integer] a hash based on {utc_offset}, {std_offset} and
100
+ # {abbreviation}.
65
101
  def hash
66
- utc_offset.hash ^ std_offset.hash ^ abbreviation.hash
102
+ [@base_utc_offset, @std_offset, @abbreviation].hash
67
103
  end
68
-
69
- # Returns internal object state as a programmer-readable string.
104
+
105
+ # @return [String] the internal object state as a programmer-readable
106
+ # `String`.
70
107
  def inspect
71
- "#<#{self.class}: #@utc_offset,#@std_offset,#@abbreviation>"
108
+ "#<#{self.class}: @base_utc_offset=#{@base_utc_offset}, @std_offset=#{@std_offset}, @abbreviation=#{@abbreviation}>"
72
109
  end
73
110
  end
74
111
  end
@@ -1,204 +1,179 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  module TZInfo
2
- # A period of time in a timezone where the same offset from UTC applies.
5
+ # {TimezonePeriod} represents a period of time for a time zone where the same
6
+ # offset from UTC applies. It provides access to the observed offset, time
7
+ # zone abbreviation, start time and end time.
3
8
  #
4
- # All the methods that take times accept instances of Time or DateTime as well
5
- # as Integer timestamps.
9
+ # The period of time can be unbounded at the start, end, or both the start
10
+ # and end.
11
+ #
12
+ # @abstract Time zone period data will returned as an instance of one of the
13
+ # subclasses of {TimezonePeriod}.
6
14
  class TimezonePeriod
7
- # The TimezoneTransition that defines the start of this TimezonePeriod
8
- # (may be nil if unbounded).
9
- attr_reader :start_transition
10
-
11
- # The TimezoneTransition that defines the end of this TimezonePeriod
12
- # (may be nil if unbounded).
13
- attr_reader :end_transition
14
-
15
- # The TimezoneOffset for this period.
15
+ # @return [TimezoneOffset] the offset that applies in the period of time.
16
16
  attr_reader :offset
17
-
18
- # Initializes a new TimezonePeriod.
19
- #
20
- # TimezonePeriod instances should not normally be constructed manually.
21
- def initialize(start_transition, end_transition, offset = nil)
22
- @start_transition = start_transition
23
- @end_transition = end_transition
24
-
25
- if offset
26
- raise ArgumentError, 'Offset specified with transitions' if @start_transition || @end_transition
27
- @offset = offset
28
- else
29
- if @start_transition
30
- @offset = @start_transition.offset
31
- elsif @end_transition
32
- @offset = @end_transition.previous_offset
33
- else
34
- raise ArgumentError, 'No offset specified and no transitions to determine it from'
35
- end
36
- end
37
-
38
- @utc_total_offset_rational = nil
39
- end
40
-
41
- # Base offset of the timezone from UTC (seconds).
42
- def utc_offset
43
- @offset.utc_offset
44
- end
45
-
46
- # Offset from the local time where daylight savings is in effect (seconds).
47
- # E.g.: utc_offset could be -5 hours. Normally, std_offset would be 0.
48
- # During daylight savings, std_offset would typically become +1 hours.
17
+
18
+ # Initializes a {TimezonePeriod}.
19
+ #
20
+ # @param offset [TimezoneOffset] the offset that is observed for the period
21
+ # of time.
22
+ # @raise [ArgumentError] if `offset` is `nil`.
23
+ def initialize(offset)
24
+ raise ArgumentError, 'offset must be specified' unless offset
25
+ @offset = offset
26
+ end
27
+
28
+ # @return [TimezoneTransition] the transition that defines the start of this
29
+ # {TimezonePeriod} (`nil` if the start is unbounded).
30
+ def start_transition
31
+ raise_not_implemented(:start_transition)
32
+ end
33
+
34
+ # @return [TimezoneTransition] the transition that defines the end of this
35
+ # {TimezonePeriod} (`nil` if the end is unbounded).
36
+ def end_transition
37
+ raise_not_implemented(:end_transition)
38
+ end
39
+
40
+ # Returns the base offset from UTC in seconds (`observed_utc_offset -
41
+ # std_offset`). This does not include any adjustment made for daylight
42
+ # savings time and will typically remain constant throughout the year.
43
+ #
44
+ # To obtain the currently observed offset from UTC, including the effect of
45
+ # daylight savings time, use {observed_utc_offset} instead.
46
+ #
47
+ # If you require accurate {base_utc_offset} values, you should install the
48
+ # tzinfo-data gem and set {DataSources::RubyDataSource} as the {DataSource}.
49
+ # When using {DataSources::ZoneinfoDataSource}, the value of
50
+ # {base_utc_offset} has to be derived from changes to the observed UTC
51
+ # offset and DST status since it is not included in zoneinfo files.
52
+ #
53
+ # @return [Integer] the base offset from UTC in seconds.
54
+ def base_utc_offset
55
+ @offset.base_utc_offset
56
+ end
57
+ alias utc_offset base_utc_offset
58
+
59
+ # Returns the offset from the time zone's standard time in seconds
60
+ # (`observed_utc_offset - base_utc_offset`). Zero when daylight savings time
61
+ # is not in effect. Non-zero (usually 3600 = 1 hour) if daylight savings is
62
+ # being observed.
63
+ #
64
+ # If you require accurate {std_offset} values, you should install the
65
+ # tzinfo-data gem and set {DataSources::RubyDataSource} as the {DataSource}.
66
+ # When using {DataSources::ZoneinfoDataSource}, the value of {std_offset}
67
+ # has to be derived from changes to the observed UTC offset and DST status
68
+ # since it is not included in zoneinfo files.
69
+ #
70
+ # @return [Integer] the offset from the time zone's standard time in
71
+ # seconds.
49
72
  def std_offset
50
73
  @offset.std_offset
51
74
  end
52
-
53
- # The identifier of this period, e.g. "GMT" (Greenwich Mean Time) or "BST"
54
- # (British Summer Time) for "Europe/London". The returned identifier is a
55
- # symbol.
75
+
76
+ # The abbreviation that identifies this offset. For example GMT
77
+ # (Greenwich Mean Time) or BST (British Summer Time) for Europe/London.
78
+ #
79
+ # @return [String] the abbreviation that identifies this offset.
56
80
  def abbreviation
57
81
  @offset.abbreviation
58
82
  end
59
- alias :zone_identifier :abbreviation
60
-
61
- # Total offset from UTC (seconds). Equal to utc_offset + std_offset.
62
- def utc_total_offset
63
- @offset.utc_total_offset
64
- end
65
-
66
- # Total offset from UTC (days). Result is a Rational.
67
- def utc_total_offset_rational
68
- # Thread-safety: It is possible that the value of
69
- # @utc_total_offset_rational may be calculated multiple times in
70
- # concurrently executing threads. It is not worth the overhead of locking
71
- # to ensure that @zone_identifiers is only calculated once.
72
-
73
- unless @utc_total_offset_rational
74
- @utc_total_offset_rational = OffsetRationals.rational_for_offset(utc_total_offset)
75
- end
76
- @utc_total_offset_rational
77
- end
78
-
79
- # The start time of the period in UTC as a DateTime. May be nil if unbounded.
80
- def utc_start
81
- @start_transition ? @start_transition.at.to_datetime : nil
82
- end
83
-
84
- # The start time of the period in UTC as a Time. May be nil if unbounded.
85
- def utc_start_time
86
- @start_transition ? @start_transition.at.to_time : nil
87
- end
88
-
89
- # The end time of the period in UTC as a DateTime. May be nil if unbounded.
90
- def utc_end
91
- @end_transition ? @end_transition.at.to_datetime : nil
92
- end
93
-
94
- # The end time of the period in UTC as a Time. May be nil if unbounded.
95
- def utc_end_time
96
- @end_transition ? @end_transition.at.to_time : nil
97
- end
98
-
99
- # The start time of the period in local time as a DateTime. May be nil if
100
- # unbounded.
101
- def local_start
102
- @start_transition ? @start_transition.local_start_at.to_datetime : nil
103
- end
104
-
105
- # The start time of the period in local time as a Time. May be nil if
106
- # unbounded.
107
- def local_start_time
108
- @start_transition ? @start_transition.local_start_at.to_time : nil
109
- end
110
-
111
- # The end time of the period in local time as a DateTime. May be nil if
112
- # unbounded.
113
- def local_end
114
- @end_transition ? @end_transition.local_end_at.to_datetime : nil
115
- end
116
-
117
- # The end time of the period in local time as a Time. May be nil if
118
- # unbounded.
119
- def local_end_time
120
- @end_transition ? @end_transition.local_end_at.to_time : nil
121
- end
122
-
123
- # true if daylight savings is in effect for this period; otherwise false.
83
+ alias abbr abbreviation
84
+ alias zone_identifier abbreviation
85
+
86
+ # Returns the observed offset from UTC in seconds (`base_utc_offset +
87
+ # std_offset`). This includes adjustments made for daylight savings time.
88
+ #
89
+ # @return [Integer] the observed offset from UTC in seconds.
90
+ def observed_utc_offset
91
+ @offset.observed_utc_offset
92
+ end
93
+ alias utc_total_offset observed_utc_offset
94
+
95
+ # Determines if daylight savings is in effect (i.e. if {std_offset} is
96
+ # non-zero).
97
+ #
98
+ # @return [Boolean] `true` if {std_offset} is non-zero, otherwise `false`.
124
99
  def dst?
125
100
  @offset.dst?
126
101
  end
127
-
128
- # true if this period is valid for the given UTC DateTime; otherwise false.
129
- def valid_for_utc?(utc)
130
- utc_after_start?(utc) && utc_before_end?(utc)
131
- end
132
-
133
- # true if the given UTC DateTime is after the start of the period
134
- # (inclusive); otherwise false.
135
- def utc_after_start?(utc)
136
- !@start_transition || @start_transition.at <= utc
137
- end
138
-
139
- # true if the given UTC DateTime is before the end of the period
140
- # (exclusive); otherwise false.
141
- def utc_before_end?(utc)
142
- !@end_transition || @end_transition.at > utc
143
- end
144
-
145
- # true if this period is valid for the given local DateTime; otherwise false.
146
- def valid_for_local?(local)
147
- local_after_start?(local) && local_before_end?(local)
148
- end
149
-
150
- # true if the given local DateTime is after the start of the period
151
- # (inclusive); otherwise false.
152
- def local_after_start?(local)
153
- !@start_transition || @start_transition.local_start_at <= local
154
- end
155
-
156
- # true if the given local DateTime is before the end of the period
157
- # (exclusive); otherwise false.
158
- def local_before_end?(local)
159
- !@end_transition || @end_transition.local_end_at > local
160
- end
161
-
162
- # Converts a UTC DateTime to local time based on the offset of this period.
163
- def to_local(utc)
164
- @offset.to_local(utc)
165
- end
166
-
167
- # Converts a local DateTime to UTC based on the offset of this period.
168
- def to_utc(local)
169
- @offset.to_utc(local)
170
- end
171
-
172
- # Returns true if this TimezonePeriod is equal to p. This compares the
173
- # start_transition, end_transition and offset using ==.
174
- def ==(p)
175
- p.kind_of?(TimezonePeriod) &&
176
- start_transition == p.start_transition &&
177
- end_transition == p.end_transition &&
178
- offset == p.offset
179
- end
180
-
181
- # Returns true if this TimezonePeriods is equal to p. This compares the
182
- # start_transition, end_transition and offset using eql?
183
- def eql?(p)
184
- p.kind_of?(TimezonePeriod) &&
185
- start_transition.eql?(p.start_transition) &&
186
- end_transition.eql?(p.end_transition) &&
187
- offset.eql?(p.offset)
188
- end
189
-
190
- # Returns a hash of this TimezonePeriod.
191
- def hash
192
- result = @start_transition.hash ^ @end_transition.hash
193
- result ^= @offset.hash unless @start_transition || @end_transition
194
- result
195
- end
196
-
197
- # Returns internal object state as a programmer-readable string.
198
- def inspect
199
- result = "#<#{self.class}: #{@start_transition.inspect},#{@end_transition.inspect}"
200
- result << ",#{@offset.inspect}>" unless @start_transition || @end_transition
201
- result + '>'
102
+
103
+ # Returns the UTC start time of the period or `nil` if the start of the
104
+ # period is unbounded.
105
+ #
106
+ # The result is returned as a {Timestamp}. To obtain the start time as a
107
+ # `Time` or `DateTime`, call either {Timestamp#to_time to_time} or
108
+ # {Timestamp#to_datetime to_datetime} on the result.
109
+ #
110
+ # @return [Timestamp] the UTC start time of the period or `nil` if the start
111
+ # of the period is unbounded.
112
+ def starts_at
113
+ timestamp(start_transition)
114
+ end
115
+
116
+ # Returns the UTC end time of the period or `nil` if the end of the period
117
+ # is unbounded.
118
+ #
119
+ # The result is returned as a {Timestamp}. To obtain the end time as a
120
+ # `Time` or `DateTime`, call either {Timestamp#to_time to_time} or
121
+ # {Timestamp#to_datetime to_datetime} on the result.
122
+ #
123
+ # @return [Timestamp] the UTC end time of the period or `nil` if the end of
124
+ # the period is unbounded.
125
+ def ends_at
126
+ timestamp(end_transition)
127
+ end
128
+
129
+ # Returns the local start time of the period or `nil` if the start of the
130
+ # period is unbounded.
131
+ #
132
+ # The result is returned as a {TimestampWithOffset}. To obtain the start
133
+ # time as a `Time` or `DateTime`, call either {TimestampWithOffset#to_time
134
+ # to_time} or {TimestampWithOffset#to_datetime to_datetime} on the result.
135
+ #
136
+ # @return [TimestampWithOffset] the local start time of the period or `nil`
137
+ # if the start of the period is unbounded.
138
+ def local_starts_at
139
+ timestamp_with_offset(start_transition)
140
+ end
141
+
142
+ # Returns the local end time of the period or `nil` if the end of the period
143
+ # is unbounded.
144
+ #
145
+ # The result is returned as a {TimestampWithOffset}. To obtain the end time
146
+ # as a `Time` or `DateTime`, call either {TimestampWithOffset#to_time
147
+ # to_time} or {TimestampWithOffset#to_datetime to_datetime} on the result.
148
+ #
149
+ # @return [TimestampWithOffset] the local end time of the period or `nil` if
150
+ # the end of the period is unbounded.
151
+ def local_ends_at
152
+ timestamp_with_offset(end_transition)
153
+ end
154
+
155
+ private
156
+
157
+ # Raises a {NotImplementedError} to indicate that subclasses should override
158
+ # a method.
159
+ #
160
+ # @raise [NotImplementedError] always.
161
+ def raise_not_implemented(method_name)
162
+ raise NotImplementedError, "Subclasses must override #{method_name}"
163
+ end
164
+
165
+ # @param transition [TimezoneTransition] a transition or `nil`.
166
+ # @return [Timestamp] the {Timestamp} representing when a transition occurs,
167
+ # or `nil` if `transition` is `nil`.
168
+ def timestamp(transition)
169
+ transition ? transition.at : nil
170
+ end
171
+
172
+ # @param transition [TimezoneTransition] a transition or `nil`.
173
+ # @return [TimestampWithOffset] a {Timestamp} representing when a transition
174
+ # occurs with offset set to {#offset}, or `nil` if `transition` is `nil`.
175
+ def timestamp_with_offset(transition)
176
+ transition ? TimestampWithOffset.set_timezone_offset(transition.at, offset) : nil
202
177
  end
203
178
  end
204
179
  end