tzinfo 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of tzinfo might be problematic. Click here for more details.

Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGES.md +33 -0
  5. data/LICENSE +1 -1
  6. data/README.md +36 -31
  7. data/Rakefile +17 -23
  8. data/lib/tzinfo.rb +0 -22
  9. data/lib/tzinfo/country.rb +3 -22
  10. data/lib/tzinfo/country_index_definition.rb +0 -22
  11. data/lib/tzinfo/country_info.rb +0 -22
  12. data/lib/tzinfo/country_timezone.rb +46 -31
  13. data/lib/tzinfo/data_source.rb +7 -24
  14. data/lib/tzinfo/data_timezone.rb +7 -22
  15. data/lib/tzinfo/data_timezone_info.rb +0 -22
  16. data/lib/tzinfo/info_timezone.rb +0 -22
  17. data/lib/tzinfo/linked_timezone.rb +7 -22
  18. data/lib/tzinfo/linked_timezone_info.rb +0 -22
  19. data/lib/tzinfo/offset_rationals.rb +0 -22
  20. data/lib/tzinfo/ruby_core_support.rb +14 -22
  21. data/lib/tzinfo/ruby_country_info.rb +3 -25
  22. data/lib/tzinfo/ruby_data_source.rb +1 -23
  23. data/lib/tzinfo/time_or_datetime.rb +13 -27
  24. data/lib/tzinfo/timezone.rb +51 -23
  25. data/lib/tzinfo/timezone_definition.rb +0 -22
  26. data/lib/tzinfo/timezone_index_definition.rb +0 -22
  27. data/lib/tzinfo/timezone_info.rb +0 -22
  28. data/lib/tzinfo/timezone_offset.rb +0 -22
  29. data/lib/tzinfo/timezone_period.rb +1 -23
  30. data/lib/tzinfo/timezone_proxy.rb +6 -23
  31. data/lib/tzinfo/timezone_transition.rb +2 -24
  32. data/lib/tzinfo/timezone_transition_definition.rb +1 -23
  33. data/lib/tzinfo/transition_data_timezone_info.rb +0 -22
  34. data/lib/tzinfo/zoneinfo_country_info.rb +1 -23
  35. data/lib/tzinfo/zoneinfo_data_source.rb +177 -61
  36. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -22
  37. data/test/tc_country.rb +6 -24
  38. data/test/tc_country_index_definition.rb +1 -23
  39. data/test/tc_country_info.rb +1 -23
  40. data/test/tc_country_timezone.rb +82 -62
  41. data/test/tc_data_source.rb +22 -24
  42. data/test/tc_data_timezone.rb +12 -24
  43. data/test/tc_data_timezone_info.rb +1 -23
  44. data/test/tc_info_timezone.rb +1 -23
  45. data/test/tc_linked_timezone.rb +37 -24
  46. data/test/tc_linked_timezone_info.rb +1 -23
  47. data/test/tc_offset_rationals.rb +1 -23
  48. data/test/tc_ruby_core_support.rb +84 -33
  49. data/test/tc_ruby_country_info.rb +5 -27
  50. data/test/tc_ruby_data_source.rb +1 -23
  51. data/test/tc_time_or_datetime.rb +44 -36
  52. data/test/tc_timezone.rb +32 -48
  53. data/test/tc_timezone_definition.rb +1 -23
  54. data/test/tc_timezone_index_definition.rb +1 -23
  55. data/test/tc_timezone_info.rb +1 -23
  56. data/test/tc_timezone_london.rb +1 -23
  57. data/test/tc_timezone_melbourne.rb +1 -23
  58. data/test/tc_timezone_new_york.rb +1 -23
  59. data/test/tc_timezone_offset.rb +1 -23
  60. data/test/tc_timezone_period.rb +5 -27
  61. data/test/tc_timezone_proxy.rb +34 -28
  62. data/test/tc_timezone_transition.rb +1 -23
  63. data/test/tc_timezone_transition_definition.rb +1 -23
  64. data/test/tc_timezone_utc.rb +1 -23
  65. data/test/tc_transition_data_timezone_info.rb +3 -25
  66. data/test/tc_zoneinfo_country_info.rb +13 -35
  67. data/test/tc_zoneinfo_data_source.rb +358 -34
  68. data/test/tc_zoneinfo_timezone_info.rb +3 -27
  69. data/test/test_utils.rb +26 -30
  70. data/test/ts_all.rb +0 -22
  71. data/test/ts_all_ruby.rb +0 -22
  72. data/test/ts_all_zoneinfo.rb +0 -22
  73. data/test/tzinfo-data/tzinfo/data.rb +0 -22
  74. data/test/tzinfo-data/tzinfo/data/version.rb +0 -22
  75. data/tzinfo.gemspec +2 -2
  76. metadata +80 -80
  77. metadata.gz.sig +1 -3
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2005-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  require 'date'
24
2
  require 'set'
25
3
  require 'thread_safe'
@@ -327,6 +305,45 @@ module TZInfo
327
305
  raise UnknownTimezone, 'TZInfo::Timezone constructed directly'
328
306
  end
329
307
 
308
+ # Returns the canonical Timezone instance for this Timezone.
309
+ #
310
+ # The IANA Time Zone database contains two types of definition: Zones and
311
+ # Links. Zones are defined by rules that set out when transitions occur.
312
+ # Links are just references to fully defined Zone, creating an alias for
313
+ # that Zone.
314
+ #
315
+ # Links are commonly used where a time zone has been renamed in a
316
+ # release of the Time Zone database. For example, the Zone US/Eastern was
317
+ # renamed as America/New_York. A US/Eastern Link was added in its place,
318
+ # linking to (and creating an alias for) for America/New_York.
319
+ #
320
+ # Links are also used for time zones that are currently identical to a full
321
+ # Zone, but that are administered seperately. For example, Europe/Vatican is
322
+ # a Link to (and alias for) Europe/Rome.
323
+ #
324
+ # For a full Zone, canonical_zone returns self.
325
+ #
326
+ # For a Link, canonical_zone returns a Timezone instance representing the
327
+ # full Zone that the link targets.
328
+ #
329
+ # TZInfo can be used with different data sources (see the documentation for
330
+ # TZInfo::DataSource). Please note that some DataSource implementations may
331
+ # not support distinguishing between full Zones and Links and will treat all
332
+ # time zones as full Zones. In this case, the canonical_zone will always
333
+ # return self.
334
+ #
335
+ # There are two built-in DataSource implementations. RubyDataSource (which
336
+ # will be used if the tzinfo-data gem is available) supports Link zones.
337
+ # ZoneinfoDataSource returns Link zones as if they were full Zones. If the
338
+ # canonical_zone or canonical_identifier methods are required, the
339
+ # tzinfo-data gem should be installed.
340
+ #
341
+ # The TZInfo::DataSource.get method can be used to check which DataSource
342
+ # implementation is being used.
343
+ def canonical_zone
344
+ raise UnknownTimezone, 'TZInfo::Timezone constructed directly'
345
+ end
346
+
330
347
  # Returns the TimezonePeriod for the given local time. local can either be
331
348
  # a DateTime, Time or integer timestamp (Time.to_i). Any timezone
332
349
  # information in local is ignored (it is treated as a time in the current
@@ -514,6 +531,14 @@ module TZInfo
514
531
  end
515
532
  end
516
533
 
534
+ # Returns the canonical identifier for this Timezone.
535
+ #
536
+ # This is a shortcut for calling canonical_zone.identifier. Please refer
537
+ # to the canonical_zone documentation for further information.
538
+ def canonical_identifier
539
+ canonical_zone.identifier
540
+ end
541
+
517
542
  # Returns the current time in the timezone as a Time.
518
543
  def now
519
544
  utc_to_local(Time.now.utc)
@@ -558,10 +583,13 @@ module TZInfo
558
583
 
559
584
  # Compares two Timezones based on their identifier. Returns -1 if tz is less
560
585
  # than self, 0 if tz is equal to self and +1 if tz is greater than self.
586
+ #
587
+ # Returns nil if tz is not comparable with Timezone instances.
561
588
  def <=>(tz)
589
+ return nil unless tz.is_a?(Timezone)
562
590
  identifier <=> tz.identifier
563
591
  end
564
-
592
+
565
593
  # Returns true if and only if the identifier of tz is equal to the
566
594
  # identifier of this Timezone.
567
595
  def eql?(tz)
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
 
25
3
  # TimezoneDefinition is included into Timezone definition modules.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # The timezone index file includes TimezoneIndexDefinition which provides
25
3
  # methods used to define timezones in the index.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # Represents a timezone defined by a data source.
25
3
  class TimezoneInfo
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # Represents an offset defined in a Timezone data file.
25
3
  class TimezoneOffset
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2005-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # A period of time in a timezone where the same offset from UTC applies.
25
3
  #
@@ -87,7 +65,7 @@ module TZInfo
87
65
 
88
66
  # Total offset from UTC (days). Result is a Rational.
89
67
  def utc_total_offset_rational
90
- # Thread-safey: It is possible that the value of
68
+ # Thread-safety: It is possible that the value of
91
69
  # @utc_total_offset_rational may be calculated multiple times in
92
70
  # concurrently executing threads. It is not worth the overhead of locking
93
71
  # to ensure that @zone_identifiers is only calculated once.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2005-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
 
25
3
  # A proxy class representing a timezone with a given identifier. TimezoneProxy
@@ -60,6 +38,11 @@ module TZInfo
60
38
  real_timezone.periods_for_local(local)
61
39
  end
62
40
 
41
+ # Returns the canonical zone for this Timezone.
42
+ def canonical_zone
43
+ real_timezone.canonical_zone
44
+ end
45
+
63
46
  # Dumps this TimezoneProxy for marshalling.
64
47
  def _dump(limit)
65
48
  identifier
@@ -77,7 +60,7 @@ module TZInfo
77
60
  end
78
61
 
79
62
  def real_timezone
80
- # Thread-safey: It is possible that the value of @real_timezone may be
63
+ # Thread-safety: It is possible that the value of @real_timezone may be
81
64
  # calculated multiple times in concurrently executing threads. It is not
82
65
  # worth the overhead of locking to ensure that @real_timezone is only
83
66
  # calculated once.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # Represents a transition from one timezone offset to another at a particular
25
3
  # date and time.
@@ -60,7 +38,7 @@ module TZInfo
60
38
  # causes the previous observance to end (calculated from at using
61
39
  # previous_offset).
62
40
  def local_end_at
63
- # Thread-safey: It is possible that the value of @local_end_at may be
41
+ # Thread-safety: It is possible that the value of @local_end_at may be
64
42
  # calculated multiple times in concurrently executing threads. It is not
65
43
  # worth the overhead of locking to ensure that @local_end_at is only
66
44
  # calculated once.
@@ -84,7 +62,7 @@ module TZInfo
84
62
  # A TimeOrDateTime instance representing the local time when this transition
85
63
  # causes the next observance to start (calculated from at using offset).
86
64
  def local_start_at
87
- # Thread-safey: It is possible that the value of @local_start_at may be
65
+ # Thread-safety: It is possible that the value of @local_start_at may be
88
66
  # calculated multiple times in concurrently executing threads. It is not
89
67
  # worth the overhead of locking to ensure that @local_start_at is only
90
68
  # calculated once.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # A TimezoneTransition defined by as integer timestamp, as a rational to
25
3
  # create a DateTime or as both.
@@ -88,7 +66,7 @@ module TZInfo
88
66
  # A TimeOrDateTime instance representing the UTC time when this transition
89
67
  # occurs.
90
68
  def at
91
- # Thread-safey: It is possible that the value of @at may be calculated
69
+ # Thread-safety: It is possible that the value of @at may be calculated
92
70
  # multiple times in concurrently executing threads. It is not worth the
93
71
  # overhead of locking to ensure that @at is only calculated once.
94
72
 
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2006-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # Raised if no offsets have been defined when calling period_for_utc or
25
3
  # periods_for_local. Indicates an error in the timezone data.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # Represents information about a country returned by ZoneinfoDataSource.
25
3
  #
@@ -36,7 +14,7 @@ module TZInfo
36
14
  # Returns a frozen array of all the zone identifiers for the country ordered
37
15
  # geographically, most populous first.
38
16
  def zone_identifiers
39
- # Thread-safey: It is possible that the value of @zone_identifiers may be
17
+ # Thread-safety: It is possible that the value of @zone_identifiers may be
40
18
  # calculated multiple times in concurrently executing threads. It is not
41
19
  # worth the overhead of locking to ensure that @zone_identifiers is only
42
20
  # calculated once.
@@ -1,25 +1,3 @@
1
- #--
2
- # Copyright (c) 2012-2013 Philip Ross
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #++
22
-
23
1
  module TZInfo
24
2
  # An InvalidZoneinfoDirectory exception is raised if the DataSource is
25
3
  # set to a specific zoneinfo path, which is not a valid zoneinfo directory
@@ -95,12 +73,19 @@ module TZInfo
95
73
  # zoneinfo support, then you may want to consider using TZInfo::RubyDataSource
96
74
  # instead.
97
75
  class ZoneinfoDataSource < DataSource
98
- # The default value of ZoneInfoDataSource.search_path.
76
+ # The default value of ZoneinfoDataSource.search_path.
99
77
  DEFAULT_SEARCH_PATH = ['/usr/share/zoneinfo', '/usr/share/lib/zoneinfo', '/etc/zoneinfo'].freeze
100
78
 
79
+ # The default value of ZoneinfoDataSource.alternate_iso3166_tab_search_path.
80
+ DEFAULT_ALTERNATE_ISO3166_TAB_SEARCH_PATH = ['/usr/share/misc/iso3166.tab', '/usr/share/misc/iso3166'].freeze
81
+
101
82
  # Paths to be checked to find the system zoneinfo directory.
102
83
  @@search_path = DEFAULT_SEARCH_PATH.dup
103
84
 
85
+ # Paths to possible alternate iso3166.tab files (used to locate the
86
+ # system-wide iso3166.tab files on FreeBSD and OpenBSD).
87
+ @@alternate_iso3166_tab_search_path = DEFAULT_ALTERNATE_ISO3166_TAB_SEARCH_PATH.dup
88
+
104
89
  # An Array of directories that will be checked to find the system zoneinfo
105
90
  # directory.
106
91
  #
@@ -121,15 +106,31 @@ module TZInfo
121
106
  #
122
107
  # Set to nil to revert to the default paths.
123
108
  def self.search_path=(search_path)
124
- if search_path
125
- if search_path.kind_of?(String)
126
- @@search_path = search_path.split(File::PATH_SEPARATOR)
127
- else
128
- @@search_path = search_path.collect {|p| p.to_s}
129
- end
130
- else
131
- @@search_path = DEFAULT_SEARCH_PATH.dup
132
- end
109
+ @@search_path = process_search_path(search_path, DEFAULT_SEARCH_PATH)
110
+ end
111
+
112
+ # An Array of paths that will be checked to find an alternate iso3166.tab
113
+ # file if one was not included in the zoneinfo directory (for example, on
114
+ # FreeBSD and OpenBSD systems).
115
+ #
116
+ # Paths are checked in the order they appear in the array.
117
+ #
118
+ # The default value is ['/usr/share/misc/iso3166.tab', '/usr/share/misc/iso3166'].
119
+ def self.alternate_iso3166_tab_search_path
120
+ @@alternate_iso3166_tab_search_path
121
+ end
122
+
123
+ # Sets the paths to check to locate an alternate iso3166.tab file if one was
124
+ # not included in the zoneinfo directory.
125
+ #
126
+ # Can be set to an Array of directories or a String containing directories
127
+ # separated with File::PATH_SEPARATOR.
128
+ #
129
+ # Paths are checked in the order they appear in the array.
130
+ #
131
+ # Set to nil to revert to the default paths.
132
+ def self.alternate_iso3166_tab_search_path=(alternate_iso3166_tab_search_path)
133
+ @@alternate_iso3166_tab_search_path = process_search_path(alternate_iso3166_tab_search_path, DEFAULT_ALTERNATE_ISO3166_TAB_SEARCH_PATH)
133
134
  end
134
135
 
135
136
  # The zoneinfo directory being used.
@@ -138,33 +139,50 @@ module TZInfo
138
139
  # Creates a new ZoneinfoDataSource.
139
140
  #
140
141
  # If zoneinfo_dir is specified, it will be checked and used as the source
141
- # of zoneinfo files. If the directory does not contain zone.tab and
142
- # iso3166.tab files, InvalidZoneinfoDirectory will be raised.
142
+ # of zoneinfo files.
143
+ #
144
+ # The directory must contain iso3166.tab and zone.tab files. These may
145
+ # either be included in the root of the directory or in a 'tab'
146
+ # sub-directory named 'country.tab' and 'zone_sun.tab' respectively (as is
147
+ # the case on Solaris.
148
+ #
149
+ # Additionally, the path to iso3166.tab can be overridden using the
150
+ # alternate_iso3166_tab_path parameter.
151
+ #
152
+ # InvalidZoneinfoDirectory will be raised if the iso3166.tab and zone.tab
153
+ # files cannot be found using the zoneinfo_dir and alternate_iso3166_tab_path
154
+ # parameters.
143
155
  #
144
156
  # If zoneinfo_dir is not specified or nil, the paths referenced in
145
157
  # search_path are searched in order to find a valid zoneinfo directory
146
- # (one that contains files named zone.tab and iso3166.tab). If no valid
147
- # zoneinfo directory is found ZoneinfoDirectoryNotFound will be raised.
148
- def initialize(zoneinfo_dir = nil)
158
+ # (one that contains zone.tab and iso3166.tab files as above).
159
+ #
160
+ # The paths referenced in alternate_iso3166_tab_search_path are also
161
+ # searched to find an iso3166.tab file if one of the searched zoneinfo
162
+ # directories doesn't contain an iso3166.tab file.
163
+ #
164
+ # If no valid directory can be found by searching, ZoneinfoDirectoryNotFound
165
+ # will be raised.
166
+ def initialize(zoneinfo_dir = nil, alternate_iso3166_tab_path = nil)
149
167
  if zoneinfo_dir
150
- unless valid_zoneinfo_dir?(zoneinfo_dir)
168
+ iso3166_tab_path, zone_tab_path = validate_zoneinfo_dir(zoneinfo_dir, alternate_iso3166_tab_path)
169
+
170
+ unless iso3166_tab_path && zone_tab_path
151
171
  raise InvalidZoneinfoDirectory, "#{zoneinfo_dir} is not a directory or doesn't contain iso3166.tab and zone.tab files."
152
172
  end
173
+
153
174
  @zoneinfo_dir = zoneinfo_dir
154
175
  else
155
- @zoneinfo_dir = self.class.search_path.detect do |path|
156
- valid_zoneinfo_dir?(path)
157
- end
176
+ @zoneinfo_dir, iso3166_tab_path, zone_tab_path = find_zoneinfo_dir
158
177
 
159
- unless @zoneinfo_dir
178
+ unless @zoneinfo_dir && iso3166_tab_path && zone_tab_path
160
179
  raise ZoneinfoDirectoryNotFound, "None of the paths included in TZInfo::ZoneinfoDataSource.search_path are valid zoneinfo directories."
161
180
  end
162
181
  end
163
182
 
164
183
  @zoneinfo_dir = File.expand_path(@zoneinfo_dir).freeze
165
- @zoneinfo_prefix = (@zoneinfo_dir + File::SEPARATOR).freeze
166
184
  @timezone_index = load_timezone_index.freeze
167
- @country_index = load_country_index.freeze
185
+ @country_index = load_country_index(iso3166_tab_path, zone_tab_path).freeze
168
186
  end
169
187
 
170
188
  # Returns a TimezoneInfo instance for a given identifier.
@@ -244,10 +262,77 @@ module TZInfo
244
262
 
245
263
  private
246
264
 
247
- # Tests whether a path represents a valid zoneinfo directory (i.e.
248
- # is a directory and contains zone.tab and iso3166.tab files).
249
- def valid_zoneinfo_dir?(path)
250
- File.directory?(path) && File.file?(File.join(path, 'zone.tab')) && File.file?(File.join(path, 'iso3166.tab'))
265
+ # Processes a path for use as the search_path or
266
+ # alternate_iso3166_tab_search_path.
267
+ def self.process_search_path(path, default)
268
+ if path
269
+ if path.kind_of?(String)
270
+ path.split(File::PATH_SEPARATOR)
271
+ else
272
+ path.collect {|p| p.to_s}
273
+ end
274
+ else
275
+ default.dup
276
+ end
277
+ end
278
+
279
+ # Validates a zoneinfo directory and returns the paths to the iso3166.tab
280
+ # and zone.tab files if valid. If the directory is not valid, returns nil.
281
+ #
282
+ # The path to the iso3166.tab file may be overriden by passing in a path.
283
+ # This is treated as either absolute or relative to the current working
284
+ # directory.
285
+ def validate_zoneinfo_dir(path, iso3166_tab_path = nil)
286
+ if File.directory?(path)
287
+ if iso3166_tab_path
288
+ return nil unless File.file?(iso3166_tab_path)
289
+ else
290
+ iso3166_tab_path = resolve_tab_path(path, 'iso3166.tab', 'country.tab')
291
+ return nil unless iso3166_tab_path
292
+ end
293
+
294
+ zone_tab_path = resolve_tab_path(path, 'zone.tab', 'zone_sun.tab')
295
+ return nil unless zone_tab_path
296
+
297
+ [iso3166_tab_path, zone_tab_path]
298
+ else
299
+ nil
300
+ end
301
+ end
302
+
303
+ # Attempts to resolve the path to a tab file given its standard name and
304
+ # tab sub-directory name (as used on Solaris).
305
+ def resolve_tab_path(zoneinfo_path, standard_name, tab_name)
306
+ path = File.join(zoneinfo_path, standard_name)
307
+ return path if File.file?(path)
308
+
309
+ path = File.join(zoneinfo_path, 'tab', tab_name)
310
+ return path if File.file?(path)
311
+
312
+ nil
313
+ end
314
+
315
+ # Finds a zoneinfo directory using search_path and
316
+ # alternate_iso3166_tab_search_path. Returns the paths to the directory,
317
+ # the iso3166.tab file and the zone.tab file or nil if not found.
318
+ def find_zoneinfo_dir
319
+ alternate_iso3166_tab_path = self.class.alternate_iso3166_tab_search_path.detect do |path|
320
+ File.file?(path)
321
+ end
322
+
323
+ self.class.search_path.each do |path|
324
+ # Try without the alternate_iso3166_tab_path first.
325
+ iso3166_tab_path, zone_tab_path = validate_zoneinfo_dir(path)
326
+ return path, iso3166_tab_path, zone_tab_path if iso3166_tab_path && zone_tab_path
327
+
328
+ if alternate_iso3166_tab_path
329
+ iso3166_tab_path, zone_tab_path = validate_zoneinfo_dir(path, alternate_iso3166_tab_path)
330
+ return path, iso3166_tab_path, zone_tab_path if iso3166_tab_path && zone_tab_path
331
+ end
332
+ end
333
+
334
+ # Not found.
335
+ nil
251
336
  end
252
337
 
253
338
  # Scans @zoneinfo_dir and returns an Array of available timezone
@@ -256,12 +341,13 @@ module TZInfo
256
341
  index = []
257
342
 
258
343
  # Ignoring particular files:
259
- # +VERSION is included in Mac OS X.
344
+ # +VERSION is included on Mac OS X.
260
345
  # localtime current local timezone (may be a link).
261
346
  # posix, posixrules and right are directories containing other versions of the zoneinfo files.
347
+ # src is a directory containing the tzdata source included on Solaris.
262
348
  # Factory is the compiled in default timezone.
263
349
 
264
- enum_timezones(nil, ['+VERSION', 'localtime', 'posix', 'posixrules', 'right', 'Factory']) do |identifier|
350
+ enum_timezones(nil, ['+VERSION', 'localtime', 'posix', 'posixrules', 'right', 'src', 'Factory']) do |identifier|
265
351
  index << identifier
266
352
  end
267
353
 
@@ -288,14 +374,31 @@ module TZInfo
288
374
 
289
375
  # Uses the iso3166.tab and zone.tab files to build an index of the
290
376
  # available countries and their timezones.
291
- def load_country_index
292
- zones = {}
377
+ def load_country_index(iso3166_tab_path, zone_tab_path)
378
+
379
+ # Handle standard 3 to 4 column zone.tab files as well as the 4 to 5
380
+ # column format used by Solaris.
381
+ #
382
+ # On Solaris, an extra column before the comment gives an optional
383
+ # linked/alternate timezone identifier (or '-' if not set).
384
+ #
385
+ # Additionally, there is a section at the end of the file for timezones
386
+ # covering regions. These are given lower-case "country" codes. The timezone
387
+ # identifier column refers to a continent instead of an identifier. These
388
+ # lines will be ignored by TZInfo.
389
+ #
390
+ # Since the last column is optional in both formats, testing for the
391
+ # Solaris format is done in two passes. The first pass identifies if there
392
+ # are any lines using 5 columns.
293
393
 
294
- File.open(File.join(@zoneinfo_dir, 'zone.tab')) do |file|
394
+ file_is_5_column = false
395
+ zone_tab = []
396
+
397
+ RubyCoreSupport.open_file(zone_tab_path, 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file|
295
398
  file.each_line do |line|
296
399
  line.chomp!
297
400
 
298
- if line =~ /\A([A-Z]{2})\t(?:([+\-])(\d{2})(\d{2})([+\-])(\d{3})(\d{2})|([+\-])(\d{2})(\d{2})(\d{2})([+\-])(\d{3})(\d{2})(\d{2}))\t([^\t]+)(?:\t([^\t]+))?\z/
401
+ if line =~ /\A([A-Z]{2})\t(?:([+\-])(\d{2})(\d{2})([+\-])(\d{3})(\d{2})|([+\-])(\d{2})(\d{2})(\d{2})([+\-])(\d{3})(\d{2})(\d{2}))\t([^\t]+)(?:\t([^\t]+))?(?:\t([^\t]+))?\z/
299
402
  code = $1
300
403
 
301
404
  if $2
@@ -307,22 +410,35 @@ module TZInfo
307
410
  end
308
411
 
309
412
  zone_identifier = $16
310
- description = $17
413
+ column4 = $17
414
+ column5 = $18
415
+
416
+ file_is_5_column = true if column5
311
417
 
312
- (zones[code] ||= []) <<
313
- CountryTimezone.new(zone_identifier, latitude.numerator, latitude.denominator,
314
- longitude.numerator, longitude.denominator, description)
418
+ zone_tab << [code, zone_identifier, latitude, longitude, column4, column5]
315
419
  end
316
420
  end
317
421
  end
318
422
 
423
+ zones = {}
424
+
425
+ zone_tab.each do |code, zone_identifier, latitude, longitude, column4, column5|
426
+ description = file_is_5_column ? column5 : column4
427
+
428
+ (zones[code] ||= []) << CountryTimezone.new(zone_identifier, latitude, longitude, description)
429
+ end
430
+
319
431
  countries = {}
320
432
 
321
- File.open(File.join(@zoneinfo_dir, 'iso3166.tab')) do |file|
433
+ RubyCoreSupport.open_file(iso3166_tab_path, 'r', :external_encoding => 'UTF-8', :internal_encoding => 'UTF-8') do |file|
322
434
  file.each_line do |line|
323
435
  line.chomp!
324
436
 
325
- if line =~ /\A([A-Z]{2})\t(.+)\z/
437
+ # Handle both the two column alpha-2 and name format used in the tz
438
+ # database as well as the 4 column alpha-2, alpha-3, numeric-3 and
439
+ # name format used by FreeBSD and OpenBSD.
440
+
441
+ if line =~ /\A([A-Z]{2})(?:\t[A-Z]{3}\t[0-9]{3})?\t(.+)\z/
326
442
  code = $1
327
443
  name = $2
328
444
  countries[code] = ZoneinfoCountryInfo.new(code, name, zones[code] || [])
@@ -333,7 +449,7 @@ module TZInfo
333
449
  countries
334
450
  end
335
451
 
336
- # Converts degrees, miunutes and seconds to a Rational
452
+ # Converts degrees, minutes and seconds to a Rational.
337
453
  def dms_to_rational(sign, degrees, minutes, seconds = nil)
338
454
  result = degrees.to_i + Rational(minutes.to_i, 60)
339
455
  result += Rational(seconds.to_i, 3600) if seconds