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
data/LICENSE CHANGED
@@ -1,19 +1,19 @@
1
- Copyright (c) 2005-2023 Philip Ross
1
+ Copyright (c) 2005-2018 Philip Ross
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
- of the Software, and to permit persons to whom the Software is furnished to do
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
8
  so, subject to the following conditions:
9
9
 
10
- The above copyright notice and this permission notice shall be included in all
10
+ The above copyright notice and this permission notice shall be included in all
11
11
  copies or substantial portions of the Software.
12
12
 
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  THE SOFTWARE.
data/README.md CHANGED
@@ -1,152 +1,406 @@
1
- TZInfo - Ruby Timezone Library
2
- ==============================
1
+ # TZInfo - Ruby Time Zone Library
3
2
 
4
- [![RubyGems](https://img.shields.io/gem/v/tzinfo?logo=rubygems&label=Gem)](https://rubygems.org/gems/tzinfo) [![Tests](https://github.com/tzinfo/tzinfo/workflows/Tests/badge.svg?branch=1.2&event=push)](https://github.com/tzinfo/tzinfo/actions?query=workflow%3ATests+branch%3A1.2+event%3Apush)
3
+ [![Gem Version](https://badge.fury.io/rb/tzinfo.svg)](https://badge.fury.io/rb/tzinfo) [![Travis CI Build Status](https://travis-ci.org/tzinfo/tzinfo.svg?branch=master)](https://travis-ci.org/tzinfo/tzinfo) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/btinuu4g8sdachj3/branch/master?svg=true)](https://ci.appveyor.com/project/philr/tzinfo/branch/master)
5
4
 
6
- [TZInfo](https://tzinfo.github.io) provides daylight savings aware
7
- transformations between times in different timezones.
5
+ [TZInfo](https://tzinfo.github.io) is a Ruby library that provides access to
6
+ time zone data and allows times to be converted using time zone rules.
8
7
 
9
8
 
10
- Data Sources
11
- ------------
9
+ ## Data Sources
12
10
 
13
- TZInfo requires a source of timezone data. There are two built-in options:
11
+ TZInfo requires a source of time zone data. There are two options:
14
12
 
15
- 1. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set
16
- of Ruby modules that are generated from the [IANA Time Zone Database](https://www.iana.org/time-zones).
17
- 2. A zoneinfo directory. Most Unix-like systems include a zoneinfo directory
18
- containing timezone definitions. These are also generated from the
19
- [IANA Time Zone Database](https://www.iana.org/time-zones).
13
+ 1. A zoneinfo directory containing timezone definition files. These files are
14
+ generated from the [IANA Time Zone Database](https://www.iana.org/time-zones)
15
+ using the `zic` utility. Most Unix-like systems include a zoneinfo directory.
16
+ 2. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set
17
+ of Ruby modules that are also generated from the IANA Time Zone Database.
20
18
 
21
- By default, TZInfo::Data will be used. If TZInfo::Data is not available (i.e.
22
- if `require 'tzinfo/data'` fails), then TZInfo will search for a zoneinfo
23
- directory instead (using the search path specified by
19
+ By default, TZInfo will attempt to use TZInfo::Data. If TZInfo::Data is not
20
+ available (i.e. if `require 'tzinfo/data'` fails), then TZInfo will search for a
21
+ zoneinfo directory instead (using the search path specified by
24
22
  `TZInfo::ZoneinfoDataSource::DEFAULT_SEARCH_PATH`).
25
23
 
26
24
  If no data source can be found, a `TZInfo::DataSourceNotFound` exception will be
27
- raised when TZInfo is used. Further information is available
28
- [in the wiki](https://tzinfo.github.io/datasourcenotfound) to help with
29
- resolving `TZInfo::DataSourceNotFound` errors.
25
+ raised when TZInfo is used. Further information is available
26
+ [in the wiki](https://tzinfo.github.io/datasourcenotfound) to help resolve
27
+ `TZInfo::DataSourceNotFound` errors.
30
28
 
31
- The default data source selection can be overridden using
29
+ The default data source selection can be overridden by calling
32
30
  `TZInfo::DataSource.set`.
33
31
 
34
- Custom data sources can also be used. See `TZInfo::DataSource.set` for
35
- further details.
32
+ Custom data sources can also be used. See the `TZInfo::DataSource.set`
33
+ documentation for further details.
36
34
 
37
35
 
38
- Installation
39
- ------------
36
+ ## Installation
40
37
 
41
- The TZInfo gem can be installed by running:
42
-
43
- gem install tzinfo
38
+ The TZInfo gem can be installed by running `gem install tzinfo` or by adding
39
+ to `gem 'tzinfo'` to your `Gemfile` and running `bundle install`.
44
40
 
45
41
  To use the Ruby modules as the data source, TZInfo::Data will also need to be
46
- installed:
47
-
48
- gem install tzinfo-data
49
-
50
-
51
- Example Usage
52
- -------------
53
-
54
- The following code will obtain the America/New_York timezone (as an instance
55
- of `TZInfo::Timezone`) and convert a time in UTC to local New York time:
56
-
57
- require 'tzinfo'
58
-
59
- tz = TZInfo::Timezone.get('America/New_York')
60
- local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
61
-
62
- Note that the local Time returned will have a UTC timezone (`local.zone` will
63
- return `"UTC"`). This is because the Time class in older (but still supported by
64
- TZInfo) versions of Ruby can only handle two timezones: UTC and the system local
65
- timezone.
66
-
67
- To convert from a local time to UTC, the `local_to_utc` method can be used as
68
- follows:
69
-
70
- utc = tz.local_to_utc(local)
71
-
72
- Note that the timezone information of the local Time object is ignored (TZInfo
73
- will just read the date and time and treat them as if there were in the `tz`
74
- timezone). The following two lines will return the same result regardless of
75
- the system's local timezone:
76
-
77
- tz.local_to_utc(Time.local(2006,6,26,1,0,0))
78
- tz.local_to_utc(Time.utc(2006,6,26,1,0,0))
79
-
80
- To obtain information about the rules in force at a particular UTC or local
81
- time, the `TZInfo::Timezone.period_for_utc` and
82
- `TZInfo::Timezone.period_for_local` methods can be used. Both of these methods
83
- return `TZInfo::TimezonePeriod` objects. The following gets the identifier for
84
- the period (in this case EDT).
85
-
86
- period = tz.period_for_utc(Time.utc(2005,8,29,15,35,0))
87
- id = period.zone_identifier
88
-
89
- The current local time in a `Timezone` can be obtained with the
90
- `TZInfo::Timezone#now` method:
91
-
92
- now = tz.now
93
-
94
- All methods in TZInfo that operate on a time can be used with either `Time` or
95
- `DateTime` instances or with Integer timestamps (i.e. as returned by
96
- `Time#to_i`). The type of the values returned will match the type passed in.
97
-
98
- A list of all the available timezone identifiers can be obtained using the
99
- `TZInfo::Timezone.all_identifiers` method. `TZInfo::Timezone.all` can be called
100
- to get an `Array` of all the `TZInfo::Timezone` instances.
101
-
102
- Timezones can also be accessed by country (using an ISO 3166-1 alpha-2 country
103
- code). The following code retrieves the `TZInfo::Country` instance representing
104
- the USA (country code 'US') and then gets all the timezone identifiers used in
105
- the USA.
106
-
107
- us = TZInfo::Country.get('US')
108
- timezones = us.zone_identifiers
109
-
110
- The `TZInfo::Country#zone_info` method provides an additional description and
111
- geographic location for each timezone in a country.
112
-
113
- A list of all the available country codes can be obtained using the
114
- `TZInfo::Country.all_codes` method. `TZInfo::Country.all` can be called to get
115
- an `Array` of all the `Country` instances.
116
-
117
- For further detail, please refer to the API documentation for the
42
+ installed by running `gem install tzinfo-data` or by adding `gem 'tzinfo-data'`
43
+ to your `Gemfile`.
44
+
45
+
46
+ ## IANA Time Zone Database
47
+
48
+ The data returned and used by TZInfo is sourced from the
49
+ [IANA Time Zone Database](http://www.iana.org/time-zones). The
50
+ [Theory and pragmatics of the tz code and data](https://data.iana.org/time-zones/theory.html)
51
+ document gives details of how the data is organized and managed.
52
+
53
+
54
+ ## Example Usage
55
+
56
+ To use TZInfo, it must first be required with:
57
+
58
+ ```ruby
59
+ require 'tzinfo'
60
+ ```
61
+
62
+ The `TZInfo::Timezone` class provides access to time zone data and methods for
63
+ converting times.
64
+
65
+ The `all_identifiers` method returns a list of valid time zone identifiers:
66
+
67
+ ```ruby
68
+ identifiers = TZInfo::Timezone.all_identifiers
69
+ # => ["Africa/Adibdjan", "Africa/Accra", ..., "Zulu"]
70
+ ```
71
+
72
+ A `TZInfo::Timezone` instance representing an individual time zone can be
73
+ obtained with `TZInfo::Timezone.get`:
74
+
75
+ ```ruby
76
+ tz = TZInfo::Timezone.get('America/New_York')
77
+ # => #<TZInfo::DataTimezone: America/New_York>
78
+ ```
79
+
80
+ A time can be converted to the local time of the time zone with `to_local`:
81
+
82
+ ```ruby
83
+ tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0))
84
+ # => 2018-02-01 07:30:00 -0500
85
+ tz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))
86
+ # => 2018-07-01 08:30:00 -0400
87
+ tz.to_local(Time.new(2018, 7, 1, 13, 30, 0, '+01:00'))
88
+ # => 2018-07-01 08:30:00 -0400
89
+ ```
90
+
91
+ Local times with the appropriate offset for the time zone can be constructed
92
+ with `local_time`:
93
+
94
+ ```ruby
95
+ tz.local_time(2018, 2, 1, 7, 30, 0)
96
+ # => 2018-02-01 07:30:00 -0500
97
+ tz.local_time(2018, 7, 1, 8, 30, 0)
98
+ # => 2018-07-01 08:30:00 -0400
99
+ ```
100
+
101
+ Local times can be converted to UTC by using `local_time` and calling `utc` on
102
+ the result:
103
+
104
+ ```ruby
105
+ tz.local_time(2018, 2, 1, 7, 30, 0).utc
106
+ # => 2018-02-01 12:30:00 UTC
107
+ tz.local_time(2018, 7, 1, 8, 30, 0).utc
108
+ # => 2018-07-01 12:30:00 UTC
109
+ ```
110
+
111
+ The `local_to_utc` method can also be used to convert a time object to UTC. The
112
+ offset of the time is ignored - it is treated as if it were a local time for the
113
+ time zone:
114
+
115
+ ```ruby
116
+ tz.local_to_utc(Time.utc(2018, 2, 1, 7, 30, 0))
117
+ # => 2018-02-01 12:30:00 UTC
118
+ tz.local_to_utc(Time.new(2018, 2, 1, 7, 30, 0, '+01:00'))
119
+ # => 2018-02-01 12:30:00 UTC
120
+ ```
121
+
122
+ Information about the time zone can be obtained from returned local times:
123
+
124
+ ```ruby
125
+ local_time = tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0))
126
+ local_time.utc_offset # => -18000
127
+ local_time.dst? # => false
128
+ local_time.zone # => "EST"
129
+
130
+ local_time = tz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))
131
+ local_time.utc_offset # => -14400
132
+ local_time.dst? # => true
133
+ local_time.zone # => "EDT"
134
+ ```
135
+
136
+ Time zone information can be included when formatting times with `strftime`
137
+ using the `%z` and `%Z` directives:
138
+
139
+ ```ruby
140
+ tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0)).strftime('%Y-%m-%d %H:%M:%S %z %Z')
141
+ # => "2018-02-01 07:30:00 -0500 EST"
142
+ tz.to_local(Time.utc(2018, 7, 1, 12, 30, 0)).strftime('%Y-%m-%d %H:%M:%S %z %Z')
143
+ # => "2018-07-01 08:30:00 -0400 EDT"
144
+ ```
145
+
146
+ The `period_for` method can be used to obtain information about the observed
147
+ time zone information at a particular time as a `TZInfo::TimezonePeriod` object:
148
+
149
+ ```ruby
150
+ period = tz.period_for(Time.utc(2018, 7, 1, 12, 30, 0))
151
+ period.base_utc_offset # => -18000
152
+ period.std_offset # => 3600
153
+ period.observed_utc_offset # => -14400
154
+ period.abbreviation # => "EDT"
155
+ period.dst? # => true
156
+ period.local_starts_at.to_time # => 2018-03-11 03:00:00 -0400
157
+ period.local_ends_at.to_time # => 2018-11-04 02:00:00 -0400
158
+ ```
159
+
160
+ A list of transitions between periods where different rules are observed can be
161
+ obtained with the `transitions_up_to` method. The result is returned as an
162
+ `Array` of `TZInfo::TimezoneTransition` objects:
163
+
164
+ ```ruby
165
+ transitions = tz.transitions_up_to(Time.utc(2019, 1, 1), Time.utc(2017, 1, 1))
166
+ transitions.map do |t|
167
+ [t.local_end_at.to_time, t.offset.observed_utc_offset, t.offset.abbreviation]
168
+ end
169
+ # => [[2017-03-12 02:00:00 -0500, -14400, "EDT"],
170
+ # [2017-11-05 02:00:00 -0400, -18000, "EST"],
171
+ # [2018-03-11 02:00:00 -0500, -14400, "EDT"],
172
+ # [2018-11-04 02:00:00 -0400, -18000, "EST"]]
173
+ ```
174
+
175
+ A list of the unique offsets used by a time zone can be obtained with the
176
+ `offsets_up_to` method. The result is returned as an `Array` of
177
+ `TZInfo::TimezoneOffset` objects:
178
+
179
+ ```ruby
180
+ offsets = tz.offsets_up_to(Time.utc(2019, 1, 1))
181
+ offsets.map {|o| [o.observed_utc_offset, o.abbreviation] }
182
+ # => [[-17762, "LMT"],
183
+ # [-18000, "EST"],
184
+ # [-14400, "EDT"],
185
+ # [-14400, "EWT"],
186
+ # [-14400, "EPT"]]
187
+ ```
188
+
189
+ All `TZInfo::Timezone` methods that accept a time as a parameter can be used
190
+ with either instances of `Time`, `DateTime` or `TZInfo::Timestamp`. Arbitrary
191
+ `Time`-like objects that respond to both `to_i` and `subsec` and optionally
192
+ `utc_offset` will be treated as if they are instances of `Time`.
193
+
194
+ `TZInfo::Timezone` methods that both accept and return times will return an
195
+ object with a type matching that of the parameter (actually a
196
+ `TZInfo::TimeWithOffset`, `TZInfo::DateTimeWithOffset` or
197
+ `TZInfo::TimestampWithOffset` subclass when returning a local time):
198
+
199
+ ```ruby
200
+ tz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))
201
+ # => 2018-07-01 08:30:00 -0400
202
+ tz.to_local(DateTime.new(2018, 7, 1, 12, 30, 0))
203
+ # => #<TZInfo::DateTimeWithOffset: 2018-07-01T08:30:00-04:00 ((2458301j,45000s,0n),-14400s,2299161j)>
204
+ tz.to_local(TZInfo::Timestamp.create(2018, 7, 1, 12, 30, 0, 0, :utc))
205
+ # => #<TZInfo::TimestampWithOffset: @value=1530448200, @sub_second=0, @utc_offset=-14400, @utc=false>
206
+ ```
207
+
208
+ In addition to `local_time`, which returns `Time` instances, the
209
+ `local_datetime` and `local_timestamp` methods can be used to construct local
210
+ `DateTime` and `TZInfo::Timestamp` instances with the appropriate offset:
211
+
212
+ ```ruby
213
+ tz.local_time(2018, 2, 1, 7, 30, 0)
214
+ # => 2018-02-01 07:30:00 -0500
215
+ tz.local_datetime(2018, 2, 1, 7, 30, 0)
216
+ # => #<TZInfo::DateTimeWithOffset: 2018-02-01T07:30:00-05:00 ((2458151j,45000s,0n),-18000s,2299161j)>
217
+ tz.local_timestamp(2018, 2, 1, 7, 30, 0)
218
+ # => #<TZInfo::TimestampWithOffset: @value=1517488200, @sub_second=0, @utc_offset=-18000, @utc=false>
219
+ ```
220
+
221
+ The `local_to_utc`, `local_time`, `local_datetime` and `local_timestamp` methods
222
+ may raise a `TZInfo::PeriodNotFound` or a `TZInfo::AmbiguousTime` exception.
223
+ `TZInfo::PeriodNotFound` signals that there is no equivalent UTC time (for
224
+ example, during the transition from standard time to daylight savings time when
225
+ the clocks are moved forward and an hour is skipped). `TZInfo::AmbiguousTime`
226
+ signals that there is more than one equivalent UTC time (for example, during the
227
+ transition from daylight savings time to standard time where the clocks are
228
+ moved back and an hour is repeated):
229
+
230
+ ```ruby
231
+ tz.local_time(2018, 3, 11, 2, 30, 0, 0)
232
+ # raises TZInfo::PeriodNotFound (2018-03-11 02:30:00 is an invalid local time.)
233
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0)
234
+ # raises TZInfo::AmbiguousTime (2018-11-04 01:30:00 is an ambiguous local time.)
235
+ ```
236
+
237
+ `TZInfo::PeriodNotFound` exceptions can only be resolved by adjusting the time,
238
+ for example, by advancing an hour:
239
+
240
+ ```ruby
241
+ tz.local_time(2018, 3, 11, 3, 30, 0, 0)
242
+ # => 2018-03-11 03:30:00 -0400
243
+ ```
244
+
245
+ `TZInfo::AmbiguousTime` exceptions can be resolved by setting the `dst`
246
+ parameter and/or specifying a block to choose one of the interpretations:
247
+
248
+ ```ruby
249
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0, true)
250
+ # => 2018-11-04 01:30:00 -0400
251
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0, false)
252
+ # => 2018-11-04 01:30:00 -0500
253
+
254
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0) {|p| p.first }
255
+ # => 2018-11-04 01:30:00 -0400
256
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0) {|p| p.last }
257
+ # => 2018-11-04 01:30:00 -0500
258
+ ```
259
+
260
+ The default value of the `dst` parameter can also be set globally:
261
+
262
+ ```ruby
263
+ TZInfo::Timezone.default_dst = true
264
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0)
265
+ # => 2018-11-04 01:30:00 -0400
266
+ TZInfo::Timezone.default_dst = false
267
+ tz.local_time(2018, 11, 4, 1, 30, 0, 0)
268
+ # => 2018-11-04 01:30:00 -0500
269
+ ```
270
+
271
+ TZInfo also provides information about
272
+ [ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) countries and
273
+ their associated time zones via the `TZInfo::Country` class.
274
+
275
+ A list of valid ISO 3166-1 (alpha-2) country codes can be obtained by calling
276
+ `TZInfo::Country.all_codes`:
277
+
278
+ ```ruby
279
+ TZInfo::Country.all_codes
280
+ # => ["AD", "AE", ..., "ZW"]
281
+ ```
282
+
283
+ A `TZInfo::Country` instance representing an individual time zone can be
284
+ obtained with `TZInfo::Country.get`:
285
+
286
+ ```ruby
287
+ c = TZInfo::Country.get('US')
288
+ # => #<TZInfo::Country: US>
289
+ c.name
290
+ # => "United States"
291
+ ```
292
+
293
+ The `zone_identifiers` method returns a list of the time zone identifiers used
294
+ in a country:
295
+
296
+ ```ruby
297
+ c.zone_identifiers
298
+ # => ["America/New_York", "America/Detroit", ..., "Pacific/Honolulu"]
299
+ ```
300
+
301
+ The `zone_info` method returns further information about the time zones used in
302
+ a country as an `Array` of `TZInfo::CountryTimezone` instances:
303
+
304
+ ```ruby
305
+ zi = c.zone_info.first
306
+ zi.identifier # => "America/New_York"
307
+ zi.latitude.to_f.round(5) # => 40.71417
308
+ zi.longitude.to_f.round(5) # => -74.00639
309
+ zi.description # => "Eastern (most areas)"
310
+ ```
311
+
312
+ The `zones` method returns an `Array` of `TZInfo::Timezone` instances for a
313
+ country. A `TZInfo::Timezone` instance can be obtained from a
314
+ `TZInfo::CountryTimezone` using the `timezone` method:
315
+
316
+ ```ruby
317
+ zi.timezone.to_local(Time.utc(2018, 2, 1, 12, 30, 0))
318
+ # => 2018-02-01 07:30:00 -0500
319
+ ```
320
+
321
+ For further detail, please refer to the API documentation for the
118
322
  `TZInfo::Timezone` and `TZInfo::Country` classes.
119
323
 
120
324
 
121
- Thread-Safety
122
- -------------
325
+ ## Time Zone Selection
326
+
327
+ The Time Zone Database maintainers recommend that time zone identifiers are not
328
+ made visible to end-users (see [Names of
329
+ timezones](https://data.iana.org/time-zones/theory.html#naming)).
330
+
331
+ Instead of displaying a list of time zone identifiers, time zones can be
332
+ selected by the user's country. Call `TZInfo::Country.all` to obtain a list of
333
+ `TZInfo::Country` objects, each with a unique `code` and a `name` that can be
334
+ used for display purposes.
335
+
336
+ Most countries have a single time zone. When choosing such a country, the time
337
+ zone can be inferred and selected automatically.
338
+
339
+ ```ruby
340
+ croatia = TZInfo::Country.get('HR')
341
+ # => #<TZInfo::Country: HR>
342
+ croatia.zone_info.length
343
+ # => 1
344
+ croatia.zone_info[0].identifier
345
+ # => "Europe/Belgrade"
346
+ ```
347
+
348
+ Some countries have multiple time zones. The `zone_info` method can be used
349
+ to obtain a list of user-friendly descriptions of the available options:
350
+
351
+ ```ruby
352
+ australia = TZInfo::Country.get('AU')
353
+ # => #<TZInfo::Country: AU>
354
+ australia.zone_info.length
355
+ # => 13
356
+ australia.zone_info.map {|i| [i.identifier, i.description] }
357
+ # => [["Australia/Lord_Howe", "Lord Howe Island"],
358
+ # ["Antarctica/Macquarie", "Macquarie Island"],
359
+ # ...
360
+ # ["Australia/Eucla", "Western Australia (Eucla)"]]
361
+ ```
362
+
363
+ Please note that country information available through TZInfo is intended as an
364
+ aid to help users select a time zone data appropriate for their practical needs.
365
+ It is not intended to take or endorse any position on legal or territorial
366
+ claims.
367
+
368
+
369
+ ## Compatibility
370
+
371
+ TZInfo v2.0.0 requires a minimum of Ruby MRI 1.9.3, JRuby 1.7 (in 1.9 mode or
372
+ later) or Rubinius 3.
373
+
374
+
375
+ ## Thread-Safety
123
376
 
124
377
  The `TZInfo::Country` and `TZInfo::Timezone` classes are thread-safe. It is safe
125
- to use class and instance methods of `TZInfo::Country` and `TZInfo::Timezone` in
126
- concurrently executing threads. Instances of both classes can be shared across
378
+ to use class and instance methods of `TZInfo::Country` and `TZInfo::Timezone` in
379
+ concurrently executing threads. Instances of both classes can be shared across
127
380
  thread boundaries.
128
381
 
129
382
 
130
- Documentation
131
- -------------
383
+ ## Documentation
132
384
 
133
- API documentation for TZInfo is available on [RubyDoc.info](https://rubydoc.info/gems/tzinfo/frames).
385
+ API documentation for TZInfo is available on
386
+ [RubyDoc.info](https://www.rubydoc.info/gems/tzinfo/).
134
387
 
135
388
 
136
- License
137
- -------
389
+ ## License
138
390
 
139
391
  TZInfo is released under the MIT license, see LICENSE for details.
140
392
 
141
393
 
142
- Source Code
143
- -----------
394
+ ## Source Code
144
395
 
145
- Source code for TZInfo is available on [GitHub](https://github.com/tzinfo/tzinfo).
396
+ Source code for TZInfo is available on
397
+ [GitHub](https://github.com/tzinfo/tzinfo).
146
398
 
147
399
 
148
- Issue Tracker
149
- -------------
400
+ ## Issue Tracker
150
401
 
151
- Please post any bugs, issues, feature requests or questions to the
402
+ Please post any bugs, issues, feature requests or questions about TZInfo to the
152
403
  [GitHub issue tracker](https://github.com/tzinfo/tzinfo/issues).
404
+
405
+ Issues with the underlying time zone data should be raised on the
406
+ [Time Zone Database Discussion mailing list](https://mm.icann.org/mailman/listinfo/tz).