tzinfo 1.2.5

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 (111) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.yardopts +6 -0
  5. data/CHANGES.md +786 -0
  6. data/LICENSE +19 -0
  7. data/README.md +151 -0
  8. data/Rakefile +107 -0
  9. data/lib/tzinfo.rb +40 -0
  10. data/lib/tzinfo/country.rb +196 -0
  11. data/lib/tzinfo/country_index_definition.rb +31 -0
  12. data/lib/tzinfo/country_info.rb +42 -0
  13. data/lib/tzinfo/country_timezone.rb +135 -0
  14. data/lib/tzinfo/data_source.rb +190 -0
  15. data/lib/tzinfo/data_timezone.rb +58 -0
  16. data/lib/tzinfo/data_timezone_info.rb +55 -0
  17. data/lib/tzinfo/info_timezone.rb +30 -0
  18. data/lib/tzinfo/linked_timezone.rb +63 -0
  19. data/lib/tzinfo/linked_timezone_info.rb +26 -0
  20. data/lib/tzinfo/offset_rationals.rb +77 -0
  21. data/lib/tzinfo/ruby_core_support.rb +146 -0
  22. data/lib/tzinfo/ruby_country_info.rb +74 -0
  23. data/lib/tzinfo/ruby_data_source.rb +136 -0
  24. data/lib/tzinfo/time_or_datetime.rb +340 -0
  25. data/lib/tzinfo/timezone.rb +669 -0
  26. data/lib/tzinfo/timezone_definition.rb +36 -0
  27. data/lib/tzinfo/timezone_index_definition.rb +54 -0
  28. data/lib/tzinfo/timezone_info.rb +30 -0
  29. data/lib/tzinfo/timezone_offset.rb +101 -0
  30. data/lib/tzinfo/timezone_period.rb +245 -0
  31. data/lib/tzinfo/timezone_proxy.rb +105 -0
  32. data/lib/tzinfo/timezone_transition.rb +130 -0
  33. data/lib/tzinfo/timezone_transition_definition.rb +104 -0
  34. data/lib/tzinfo/transition_data_timezone_info.rb +274 -0
  35. data/lib/tzinfo/zoneinfo_country_info.rb +37 -0
  36. data/lib/tzinfo/zoneinfo_data_source.rb +488 -0
  37. data/lib/tzinfo/zoneinfo_timezone_info.rb +296 -0
  38. data/test/tc_country.rb +234 -0
  39. data/test/tc_country_index_definition.rb +69 -0
  40. data/test/tc_country_info.rb +16 -0
  41. data/test/tc_country_timezone.rb +173 -0
  42. data/test/tc_data_source.rb +218 -0
  43. data/test/tc_data_timezone.rb +99 -0
  44. data/test/tc_data_timezone_info.rb +18 -0
  45. data/test/tc_info_timezone.rb +34 -0
  46. data/test/tc_linked_timezone.rb +155 -0
  47. data/test/tc_linked_timezone_info.rb +23 -0
  48. data/test/tc_offset_rationals.rb +23 -0
  49. data/test/tc_ruby_core_support.rb +168 -0
  50. data/test/tc_ruby_country_info.rb +110 -0
  51. data/test/tc_ruby_data_source.rb +143 -0
  52. data/test/tc_time_or_datetime.rb +654 -0
  53. data/test/tc_timezone.rb +1350 -0
  54. data/test/tc_timezone_definition.rb +113 -0
  55. data/test/tc_timezone_index_definition.rb +73 -0
  56. data/test/tc_timezone_info.rb +11 -0
  57. data/test/tc_timezone_london.rb +143 -0
  58. data/test/tc_timezone_melbourne.rb +142 -0
  59. data/test/tc_timezone_new_york.rb +142 -0
  60. data/test/tc_timezone_offset.rb +126 -0
  61. data/test/tc_timezone_period.rb +555 -0
  62. data/test/tc_timezone_proxy.rb +136 -0
  63. data/test/tc_timezone_transition.rb +366 -0
  64. data/test/tc_timezone_transition_definition.rb +295 -0
  65. data/test/tc_timezone_utc.rb +27 -0
  66. data/test/tc_transition_data_timezone_info.rb +423 -0
  67. data/test/tc_zoneinfo_country_info.rb +78 -0
  68. data/test/tc_zoneinfo_data_source.rb +1195 -0
  69. data/test/tc_zoneinfo_timezone_info.rb +1232 -0
  70. data/test/test_utils.rb +163 -0
  71. data/test/ts_all.rb +7 -0
  72. data/test/ts_all_ruby.rb +5 -0
  73. data/test/ts_all_zoneinfo.rb +7 -0
  74. data/test/tzinfo-data/tzinfo/data.rb +8 -0
  75. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +89 -0
  76. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +315 -0
  77. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +218 -0
  78. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +19 -0
  79. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +21 -0
  80. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +21 -0
  81. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +21 -0
  82. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +261 -0
  83. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +186 -0
  84. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +321 -0
  85. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +265 -0
  86. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +220 -0
  87. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +16 -0
  88. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +927 -0
  89. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +596 -0
  90. data/test/tzinfo-data/tzinfo/data/version.rb +14 -0
  91. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  92. data/test/zoneinfo/America/New_York +0 -0
  93. data/test/zoneinfo/Australia/Melbourne +0 -0
  94. data/test/zoneinfo/EST +0 -0
  95. data/test/zoneinfo/Etc/UTC +0 -0
  96. data/test/zoneinfo/Europe/Amsterdam +0 -0
  97. data/test/zoneinfo/Europe/Andorra +0 -0
  98. data/test/zoneinfo/Europe/London +0 -0
  99. data/test/zoneinfo/Europe/Paris +0 -0
  100. data/test/zoneinfo/Europe/Prague +0 -0
  101. data/test/zoneinfo/Factory +0 -0
  102. data/test/zoneinfo/iso3166.tab +275 -0
  103. data/test/zoneinfo/leapseconds +61 -0
  104. data/test/zoneinfo/posix/Europe/London +0 -0
  105. data/test/zoneinfo/posixrules +0 -0
  106. data/test/zoneinfo/right/Europe/London +0 -0
  107. data/test/zoneinfo/zone.tab +439 -0
  108. data/test/zoneinfo/zone1970.tab +369 -0
  109. data/tzinfo.gemspec +21 -0
  110. metadata +193 -0
  111. metadata.gz.sig +2 -0
@@ -0,0 +1,55 @@
1
+ module TZInfo
2
+ # Represents a defined timezone containing transition data.
3
+ class DataTimezoneInfo < TimezoneInfo
4
+
5
+ # Returns the TimezonePeriod for the given UTC time.
6
+ def period_for_utc(utc)
7
+ raise_not_implemented('period_for_utc')
8
+ end
9
+
10
+ # Returns the set of TimezonePeriods for the given local time as an array.
11
+ # Results returned are ordered by increasing UTC start date.
12
+ # Returns an empty array if no periods are found for the given time.
13
+ def periods_for_local(local)
14
+ raise_not_implemented('periods_for_local')
15
+ end
16
+
17
+ # Returns an Array of TimezoneTransition instances representing the times
18
+ # where the UTC offset of the timezone changes.
19
+ #
20
+ # Transitions are returned up to a given date and time up to a given date
21
+ # and time, specified in UTC (utc_to).
22
+ #
23
+ # A from date and time may also be supplied using the utc_from parameter
24
+ # (also specified in UTC). If utc_from is not nil, only transitions from
25
+ # that date and time onwards will be returned.
26
+ #
27
+ # Comparisons with utc_to are exclusive. Comparisons with utc_from are
28
+ # inclusive. If a transition falls precisely on utc_to, it will be excluded.
29
+ # If a transition falls on utc_from, it will be included.
30
+ #
31
+ # Transitions returned are ordered by when they occur, from earliest to
32
+ # latest.
33
+ #
34
+ # utc_to and utc_from can be specified using either DateTime, Time or
35
+ # integer timestamps (Time.to_i).
36
+ #
37
+ # If utc_from is specified and utc_to is not greater than utc_from, then
38
+ # transitions_up_to raises an ArgumentError exception.
39
+ def transitions_up_to(utc_to, utc_from = nil)
40
+ raise_not_implemented('transitions_up_to')
41
+ end
42
+
43
+ # Constructs a Timezone instance for the timezone represented by this
44
+ # DataTimezoneInfo.
45
+ def create_timezone
46
+ DataTimezone.new(self)
47
+ end
48
+
49
+ private
50
+
51
+ def raise_not_implemented(method_name)
52
+ raise NotImplementedError, "Subclasses must override #{method_name}"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,30 @@
1
+ module TZInfo
2
+
3
+ # A Timezone based on a TimezoneInfo.
4
+ #
5
+ # @private
6
+ class InfoTimezone < Timezone #:nodoc:
7
+
8
+ # Constructs a new InfoTimezone with a TimezoneInfo instance.
9
+ def self.new(info)
10
+ tz = super()
11
+ tz.send(:setup, info)
12
+ tz
13
+ end
14
+
15
+ # The identifier of the timezone, e.g. "Europe/Paris".
16
+ def identifier
17
+ @info.identifier
18
+ end
19
+
20
+ protected
21
+ # The TimezoneInfo for this Timezone.
22
+ def info
23
+ @info
24
+ end
25
+
26
+ def setup(info)
27
+ @info = info
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ module TZInfo
2
+
3
+ # A Timezone based on a LinkedTimezoneInfo.
4
+ #
5
+ # @private
6
+ class LinkedTimezone < InfoTimezone #:nodoc:
7
+ # Returns the TimezonePeriod for the given UTC time. utc can either be
8
+ # a DateTime, Time or integer timestamp (Time.to_i). Any timezone
9
+ # information in utc is ignored (it is treated as a UTC time).
10
+ #
11
+ # If no TimezonePeriod could be found, PeriodNotFound is raised.
12
+ def period_for_utc(utc)
13
+ @linked_timezone.period_for_utc(utc)
14
+ end
15
+
16
+ # Returns the set of TimezonePeriod instances that are valid for the given
17
+ # local time as an array. If you just want a single period, use
18
+ # period_for_local instead and specify how abiguities should be resolved.
19
+ # Raises PeriodNotFound if no periods are found for the given time.
20
+ def periods_for_local(local)
21
+ @linked_timezone.periods_for_local(local)
22
+ end
23
+
24
+ # Returns an Array of TimezoneTransition instances representing the times
25
+ # where the UTC offset of the timezone changes.
26
+ #
27
+ # Transitions are returned up to a given date and time up to a given date
28
+ # and time, specified in UTC (utc_to).
29
+ #
30
+ # A from date and time may also be supplied using the utc_from parameter
31
+ # (also specified in UTC). If utc_from is not nil, only transitions from
32
+ # that date and time onwards will be returned.
33
+ #
34
+ # Comparisons with utc_to are exclusive. Comparisons with utc_from are
35
+ # inclusive. If a transition falls precisely on utc_to, it will be excluded.
36
+ # If a transition falls on utc_from, it will be included.
37
+ #
38
+ # Transitions returned are ordered by when they occur, from earliest to
39
+ # latest.
40
+ #
41
+ # utc_to and utc_from can be specified using either DateTime, Time or
42
+ # integer timestamps (Time.to_i).
43
+ #
44
+ # If utc_from is specified and utc_to is not greater than utc_from, then
45
+ # transitions_up_to raises an ArgumentError exception.
46
+ def transitions_up_to(utc_to, utc_from = nil)
47
+ @linked_timezone.transitions_up_to(utc_to, utc_from)
48
+ end
49
+
50
+ # Returns the canonical zone for this Timezone.
51
+ #
52
+ # For a LinkedTimezone, this is the canonical zone of the link target.
53
+ def canonical_zone
54
+ @linked_timezone.canonical_zone
55
+ end
56
+
57
+ protected
58
+ def setup(info)
59
+ super(info)
60
+ @linked_timezone = Timezone.get(info.link_to_identifier)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ module TZInfo
2
+ # Represents a timezone that is defined as a link or alias to another zone.
3
+ class LinkedTimezoneInfo < TimezoneInfo
4
+
5
+ # The zone that provides the data (that this zone is an alias for).
6
+ attr_reader :link_to_identifier
7
+
8
+ # Constructs a new LinkedTimezoneInfo with an identifier and the identifier
9
+ # of the zone linked to.
10
+ def initialize(identifier, link_to_identifier)
11
+ super(identifier)
12
+ @link_to_identifier = link_to_identifier
13
+ end
14
+
15
+ # Returns internal object state as a programmer-readable string.
16
+ def inspect
17
+ "#<#{self.class}: #@identifier,#@link_to_identifier>"
18
+ end
19
+
20
+ # Constructs a Timezone instance for the timezone represented by this
21
+ # DataTimezoneInfo.
22
+ def create_timezone
23
+ LinkedTimezone.new(self)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,77 @@
1
+ require 'rational' unless defined?(Rational)
2
+
3
+ module TZInfo
4
+
5
+ # Provides a method for getting Rationals for a timezone offset in seconds.
6
+ # Pre-reduced rationals are returned for all the half-hour intervals between
7
+ # -14 and +14 hours to avoid having to call gcd at runtime.
8
+ #
9
+ # @private
10
+ module OffsetRationals #:nodoc:
11
+ @@rational_cache = {
12
+ -50400 => RubyCoreSupport.rational_new!(-7,12),
13
+ -48600 => RubyCoreSupport.rational_new!(-9,16),
14
+ -46800 => RubyCoreSupport.rational_new!(-13,24),
15
+ -45000 => RubyCoreSupport.rational_new!(-25,48),
16
+ -43200 => RubyCoreSupport.rational_new!(-1,2),
17
+ -41400 => RubyCoreSupport.rational_new!(-23,48),
18
+ -39600 => RubyCoreSupport.rational_new!(-11,24),
19
+ -37800 => RubyCoreSupport.rational_new!(-7,16),
20
+ -36000 => RubyCoreSupport.rational_new!(-5,12),
21
+ -34200 => RubyCoreSupport.rational_new!(-19,48),
22
+ -32400 => RubyCoreSupport.rational_new!(-3,8),
23
+ -30600 => RubyCoreSupport.rational_new!(-17,48),
24
+ -28800 => RubyCoreSupport.rational_new!(-1,3),
25
+ -27000 => RubyCoreSupport.rational_new!(-5,16),
26
+ -25200 => RubyCoreSupport.rational_new!(-7,24),
27
+ -23400 => RubyCoreSupport.rational_new!(-13,48),
28
+ -21600 => RubyCoreSupport.rational_new!(-1,4),
29
+ -19800 => RubyCoreSupport.rational_new!(-11,48),
30
+ -18000 => RubyCoreSupport.rational_new!(-5,24),
31
+ -16200 => RubyCoreSupport.rational_new!(-3,16),
32
+ -14400 => RubyCoreSupport.rational_new!(-1,6),
33
+ -12600 => RubyCoreSupport.rational_new!(-7,48),
34
+ -10800 => RubyCoreSupport.rational_new!(-1,8),
35
+ -9000 => RubyCoreSupport.rational_new!(-5,48),
36
+ -7200 => RubyCoreSupport.rational_new!(-1,12),
37
+ -5400 => RubyCoreSupport.rational_new!(-1,16),
38
+ -3600 => RubyCoreSupport.rational_new!(-1,24),
39
+ -1800 => RubyCoreSupport.rational_new!(-1,48),
40
+ 0 => RubyCoreSupport.rational_new!(0,1),
41
+ 1800 => RubyCoreSupport.rational_new!(1,48),
42
+ 3600 => RubyCoreSupport.rational_new!(1,24),
43
+ 5400 => RubyCoreSupport.rational_new!(1,16),
44
+ 7200 => RubyCoreSupport.rational_new!(1,12),
45
+ 9000 => RubyCoreSupport.rational_new!(5,48),
46
+ 10800 => RubyCoreSupport.rational_new!(1,8),
47
+ 12600 => RubyCoreSupport.rational_new!(7,48),
48
+ 14400 => RubyCoreSupport.rational_new!(1,6),
49
+ 16200 => RubyCoreSupport.rational_new!(3,16),
50
+ 18000 => RubyCoreSupport.rational_new!(5,24),
51
+ 19800 => RubyCoreSupport.rational_new!(11,48),
52
+ 21600 => RubyCoreSupport.rational_new!(1,4),
53
+ 23400 => RubyCoreSupport.rational_new!(13,48),
54
+ 25200 => RubyCoreSupport.rational_new!(7,24),
55
+ 27000 => RubyCoreSupport.rational_new!(5,16),
56
+ 28800 => RubyCoreSupport.rational_new!(1,3),
57
+ 30600 => RubyCoreSupport.rational_new!(17,48),
58
+ 32400 => RubyCoreSupport.rational_new!(3,8),
59
+ 34200 => RubyCoreSupport.rational_new!(19,48),
60
+ 36000 => RubyCoreSupport.rational_new!(5,12),
61
+ 37800 => RubyCoreSupport.rational_new!(7,16),
62
+ 39600 => RubyCoreSupport.rational_new!(11,24),
63
+ 41400 => RubyCoreSupport.rational_new!(23,48),
64
+ 43200 => RubyCoreSupport.rational_new!(1,2),
65
+ 45000 => RubyCoreSupport.rational_new!(25,48),
66
+ 46800 => RubyCoreSupport.rational_new!(13,24),
67
+ 48600 => RubyCoreSupport.rational_new!(9,16),
68
+ 50400 => RubyCoreSupport.rational_new!(7,12)}.freeze
69
+
70
+ # Returns a Rational expressing the fraction of a day that offset in
71
+ # seconds represents (i.e. equivalent to Rational(offset, 86400)).
72
+ def rational_for_offset(offset)
73
+ @@rational_cache[offset] || Rational(offset, 86400)
74
+ end
75
+ module_function :rational_for_offset
76
+ end
77
+ end
@@ -0,0 +1,146 @@
1
+ require 'date'
2
+ require 'rational' unless defined?(Rational)
3
+
4
+ module TZInfo
5
+
6
+ # Methods to support different versions of Ruby.
7
+ #
8
+ # @private
9
+ module RubyCoreSupport #:nodoc:
10
+
11
+ # Use Rational.new! for performance reasons in Ruby 1.8.
12
+ # This has been removed from 1.9, but Rational performs better.
13
+ if Rational.respond_to? :new!
14
+ def self.rational_new!(numerator, denominator = 1)
15
+ Rational.new!(numerator, denominator)
16
+ end
17
+ else
18
+ def self.rational_new!(numerator, denominator = 1)
19
+ Rational(numerator, denominator)
20
+ end
21
+ end
22
+
23
+ # Ruby 1.8.6 introduced new! and deprecated new0.
24
+ # Ruby 1.9.0 removed new0.
25
+ # Ruby trunk revision 31668 removed the new! method.
26
+ # Still support new0 for better performance on older versions of Ruby (new0 indicates
27
+ # that the rational has already been reduced to its lowest terms).
28
+ # Fallback to jd with conversion from ajd if new! and new0 are unavailable.
29
+ if DateTime.respond_to? :new!
30
+ def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
31
+ DateTime.new!(ajd, of, sg)
32
+ end
33
+ elsif DateTime.respond_to? :new0
34
+ def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
35
+ DateTime.new0(ajd, of, sg)
36
+ end
37
+ else
38
+ HALF_DAYS_IN_DAY = rational_new!(1, 2)
39
+
40
+ def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
41
+ # Convert from an Astronomical Julian Day number to a civil Julian Day number.
42
+ jd = ajd + of + HALF_DAYS_IN_DAY
43
+
44
+ # Ruby trunk revision 31862 changed the behaviour of DateTime.jd so that it will no
45
+ # longer accept a fractional civil Julian Day number if further arguments are specified.
46
+ # Calculate the hours, minutes and seconds to pass to jd.
47
+
48
+ jd_i = jd.to_i
49
+ jd_i -= 1 if jd < 0
50
+ hours = (jd - jd_i) * 24
51
+ hours_i = hours.to_i
52
+ minutes = (hours - hours_i) * 60
53
+ minutes_i = minutes.to_i
54
+ seconds = (minutes - minutes_i) * 60
55
+
56
+ DateTime.jd(jd_i, hours_i, minutes_i, seconds, of, sg)
57
+ end
58
+ end
59
+
60
+ # DateTime in Ruby 1.8.6 doesn't consider times within the 60th second to be
61
+ # valid. When attempting to specify such a DateTime, subtract the fractional
62
+ # part and then add it back later
63
+ if Date.respond_to?(:valid_time?) && !Date.valid_time?(0, 0, rational_new!(59001, 1000)) # 0:0:59.001
64
+ def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
65
+ if !s.kind_of?(Integer) && s > 59
66
+ dt = DateTime.new(y, m, d, h, min, 59, of, sg)
67
+ dt + (s - 59) / 86400
68
+ else
69
+ DateTime.new(y, m, d, h, min, s, of, sg)
70
+ end
71
+ end
72
+ else
73
+ def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
74
+ DateTime.new(y, m, d, h, min, s, of, sg)
75
+ end
76
+ end
77
+
78
+ # Returns true if Time on the runtime platform supports Times defined
79
+ # by negative 32-bit timestamps, otherwise false.
80
+ begin
81
+ Time.at(-1)
82
+ Time.at(-2147483648)
83
+
84
+ def self.time_supports_negative
85
+ true
86
+ end
87
+ rescue ArgumentError
88
+ def self.time_supports_negative
89
+ false
90
+ end
91
+ end
92
+
93
+ # Returns true if Time on the runtime platform supports Times defined by
94
+ # 64-bit timestamps, otherwise false.
95
+ begin
96
+ Time.at(-2147483649)
97
+ Time.at(2147483648)
98
+
99
+ def self.time_supports_64bit
100
+ true
101
+ end
102
+ rescue RangeError
103
+ def self.time_supports_64bit
104
+ false
105
+ end
106
+ end
107
+
108
+ # Return the result of Time#nsec if it exists, otherwise return the
109
+ # result of Time#usec * 1000.
110
+ if Time.method_defined?(:nsec)
111
+ def self.time_nsec(time)
112
+ time.nsec
113
+ end
114
+ else
115
+ def self.time_nsec(time)
116
+ time.usec * 1000
117
+ end
118
+ end
119
+
120
+ # Call String#force_encoding if this version of Ruby has encoding support
121
+ # otherwise treat as a no-op.
122
+ if String.method_defined?(:force_encoding)
123
+ def self.force_encoding(str, encoding)
124
+ str.force_encoding(encoding)
125
+ end
126
+ else
127
+ def self.force_encoding(str, encoding)
128
+ str
129
+ end
130
+ end
131
+
132
+
133
+ # Wrapper for File.open that supports passing hash options for specifying
134
+ # encodings on Ruby 1.9+. The options are ignored on earlier versions of
135
+ # Ruby.
136
+ if RUBY_VERSION =~ /\A1\.[0-8]\./
137
+ def self.open_file(file_name, mode, opts, &block)
138
+ File.open(file_name, mode, &block)
139
+ end
140
+ else
141
+ def self.open_file(file_name, mode, opts, &block)
142
+ File.open(file_name, mode, opts, &block)
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,74 @@
1
+ module TZInfo
2
+ # Represents information about a country returned by RubyDataSource.
3
+ #
4
+ # @private
5
+ class RubyCountryInfo < CountryInfo #:nodoc:
6
+ # Constructs a new CountryInfo with an ISO 3166 country code, name and
7
+ # block. The block will be evaluated to obtain the timezones for the
8
+ # country when the zones are first needed.
9
+ def initialize(code, name, &block)
10
+ super(code, name)
11
+ @block = block
12
+ @zones = nil
13
+ @zone_identifiers = nil
14
+ end
15
+
16
+ # Returns a frozen array of all the zone identifiers for the country. These
17
+ # are in the order they were added using the timezone method.
18
+ def zone_identifiers
19
+ # Thread-safety: It is possible that the value of @zone_identifiers may be
20
+ # calculated multiple times in concurrently executing threads. It is not
21
+ # worth the overhead of locking to ensure that @zone_identifiers is only
22
+ # calculated once.
23
+
24
+ unless @zone_identifiers
25
+ result = zones.collect {|zone| zone.identifier}.freeze
26
+ return result if frozen?
27
+ @zone_identifiers = result
28
+ end
29
+
30
+ @zone_identifiers
31
+ end
32
+
33
+ # Returns a frozen array of all the timezones for the for the country as
34
+ # CountryTimezone instances. These are in the order they were added using
35
+ # the timezone method.
36
+ def zones
37
+ # Thread-safety: It is possible that the value of @zones may be
38
+ # calculated multiple times in concurrently executing threads. It is not
39
+ # worth the overhead of locking to ensure that @zones is only
40
+ # calculated once.
41
+
42
+ unless @zones
43
+ zones = Zones.new
44
+ @block.call(zones) if @block
45
+ result = zones.list.freeze
46
+ return result if frozen?
47
+ @block = nil
48
+ @zones = result
49
+ end
50
+
51
+ @zones
52
+ end
53
+
54
+ # An instance of the Zones class is passed to the block used to define
55
+ # timezones.
56
+ #
57
+ # @private
58
+ class Zones #:nodoc:
59
+ attr_reader :list
60
+
61
+ def initialize
62
+ @list = []
63
+ end
64
+
65
+ # Called by the index data to define a timezone for the country.
66
+ def timezone(identifier, latitude_numerator, latitude_denominator,
67
+ longitude_numerator, longitude_denominator, description = nil)
68
+ @list << CountryTimezone.new!(identifier, latitude_numerator,
69
+ latitude_denominator, longitude_numerator, longitude_denominator,
70
+ description)
71
+ end
72
+ end
73
+ end
74
+ end