tzinfo 1.2.11 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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).