lazier 3.5.1 → 3.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rubocop.yml +29 -0
- data/.travis-gemfile +1 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -3
- data/README.md +1 -1
- data/doc/Lazier.html +56 -68
- data/doc/Lazier/Boolean.html +4 -4
- data/doc/Lazier/Configuration.html +5 -5
- data/doc/Lazier/DateTime.html +29 -29
- data/doc/Lazier/DateTime/ClassMethods.html +136 -124
- data/doc/Lazier/Exceptions.html +4 -4
- data/doc/Lazier/Exceptions/Debug.html +4 -4
- data/doc/Lazier/Exceptions/MissingTranslation.html +4 -4
- data/doc/Lazier/Hash.html +144 -32
- data/doc/Lazier/I18n.html +109 -103
- data/doc/Lazier/Localizer.html +4 -4
- data/doc/Lazier/Math.html +4 -4
- data/doc/Lazier/Math/ClassMethods.html +4 -4
- data/doc/Lazier/Object.html +357 -243
- data/doc/Lazier/Pathname.html +4 -4
- data/doc/Lazier/Settings.html +58 -34
- data/doc/Lazier/String.html +6 -6
- data/doc/Lazier/TimeZone.html +86 -86
- data/doc/Lazier/TimeZone/ClassMethods.html +66 -68
- data/doc/Lazier/Version.html +5 -5
- data/doc/_index.html +5 -5
- data/doc/css/style.css +1 -0
- data/doc/file.README.html +4 -4
- data/doc/frames.html +1 -1
- data/doc/index.html +4 -4
- data/doc/method_list.html +103 -91
- data/doc/top-level-namespace.html +4 -4
- data/lazier.gemspec +2 -2
- data/lib/lazier.rb +59 -22
- data/lib/lazier/boolean.rb +1 -1
- data/lib/lazier/configuration.rb +21 -20
- data/lib/lazier/datetime.rb +127 -101
- data/lib/lazier/hash.rb +20 -12
- data/lib/lazier/i18n.rb +33 -32
- data/lib/lazier/math.rb +1 -1
- data/lib/lazier/object.rb +102 -56
- data/lib/lazier/pathname.rb +1 -1
- data/lib/lazier/settings.rb +4 -2
- data/lib/lazier/string.rb +3 -3
- data/lib/lazier/version.rb +1 -1
- data/spec/lazier/datetime_spec.rb +1 -1
- data/spec/lazier/hash_spec.rb +2 -2
- data/spec/lazier/object_spec.rb +16 -0
- data/spec/lazier/string_spec.rb +4 -10
- data/spec/lazier_spec.rb +9 -9
- data/spec/spec_helper.rb +1 -1
- metadata +7 -6
@@ -6,7 +6,7 @@
|
|
6
6
|
<title>
|
7
7
|
Top Level Namespace
|
8
8
|
|
9
|
-
— Documentation by YARD 0.8.7.
|
9
|
+
— Documentation by YARD 0.8.7.4
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
@@ -17,7 +17,7 @@
|
|
17
17
|
<script type="text/javascript" charset="utf-8">
|
18
18
|
hasFrames = window.top.frames.main ? true : false;
|
19
19
|
relpath = '';
|
20
|
-
framesUrl = "frames.html#!"
|
20
|
+
framesUrl = "frames.html#!top-level-namespace.html";
|
21
21
|
</script>
|
22
22
|
|
23
23
|
|
@@ -103,9 +103,9 @@
|
|
103
103
|
</div>
|
104
104
|
|
105
105
|
<div id="footer">
|
106
|
-
Generated on Sun
|
106
|
+
Generated on Sun Apr 27 17:16:41 2014 by
|
107
107
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
108
|
-
0.8.7.
|
108
|
+
0.8.7.4 (ruby-2.1.0).
|
109
109
|
</div>
|
110
110
|
|
111
111
|
</body>
|
data/lazier.gemspec
CHANGED
@@ -28,6 +28,6 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_dependency("json", "~> 1.8.1")
|
29
29
|
gem.add_dependency("activesupport", ">= 3.2.13") # We don't use ~> to enable use with 4.0
|
30
30
|
gem.add_dependency("tzinfo", ">= 0.3.37") # We don't use ~> to enable use with 0.3.37 (required by activesupport 4.0) and 1.x, which is the latest available
|
31
|
-
gem.add_dependency("r18n-desktop", "~> 1.1.
|
32
|
-
gem.add_dependency("hashie", "~> 2.
|
31
|
+
gem.add_dependency("r18n-desktop", "~> 1.1.10")
|
32
|
+
gem.add_dependency("hashie", "~> 2.1.1")
|
33
33
|
end
|
data/lib/lazier.rb
CHANGED
@@ -6,11 +6,12 @@
|
|
6
6
|
|
7
7
|
require "json"
|
8
8
|
require "tzinfo"
|
9
|
+
require "active_support"
|
9
10
|
require "active_support/core_ext"
|
10
11
|
require "r18n-desktop"
|
11
12
|
require "hashie"
|
12
13
|
|
13
|
-
require "lazier/version"
|
14
|
+
require "lazier/version" unless defined?(Lazier::Version)
|
14
15
|
require "lazier/exceptions"
|
15
16
|
require "lazier/i18n"
|
16
17
|
require "lazier/localizer"
|
@@ -47,7 +48,7 @@ module Lazier
|
|
47
48
|
# @option pathname Extensions for path objects.
|
48
49
|
# @return [Settings] The settings for the extensions.
|
49
50
|
def self.load!(*what)
|
50
|
-
modules = what.present? ? what.flatten.uniq.compact.map(&:to_s) :
|
51
|
+
modules = what.present? ? what.flatten.uniq.compact.map(&:to_s) : %w(object boolean string hash datetime math pathname)
|
51
52
|
modules.each { |w| ::Lazier.send("load_#{w}") }
|
52
53
|
|
53
54
|
yield if block_given?
|
@@ -79,6 +80,7 @@ module Lazier
|
|
79
80
|
|
80
81
|
# Loads Hash extensions.
|
81
82
|
def self.load_hash
|
83
|
+
clean_hash_compact
|
82
84
|
::Hash.class_eval { include ::Lazier::Hash }
|
83
85
|
end
|
84
86
|
|
@@ -112,22 +114,15 @@ module Lazier
|
|
112
114
|
|
113
115
|
# Finds a class to instantiate.
|
114
116
|
#
|
115
|
-
# @param cls [Symbol|String|Object] If a `String` or a `Symbol` or a `Class`, then it will be the class to instantiate.
|
117
|
+
# @param cls [Symbol|String|Object] If a `String` or a `Symbol` or a `Class`, then it will be the class to instantiate.
|
118
|
+
# Otherwise the class of the object will returned.
|
116
119
|
# @param scope [String] An additional scope to find the class. `%CLASS%`, `%`, `$`, `?` and `@` will be substituted with the class name.
|
117
120
|
# @param only_in_scope [Boolean] If only try to instantiate the class in the scope.
|
118
121
|
# @return [Class] The found class.
|
119
122
|
def self.find_class(cls, scope = "::%CLASS%", only_in_scope = false)
|
120
|
-
if cls.is_a?(::String) || cls.is_a?(::Symbol)
|
121
|
-
rv =
|
122
|
-
|
123
|
-
|
124
|
-
if only_in_scope then
|
125
|
-
cls.gsub!(/^::/, "") # Mark only search only inside scope
|
126
|
-
else
|
127
|
-
rv = search_class(cls) # Search outside scope
|
128
|
-
end
|
129
|
-
|
130
|
-
rv = search_class(scope.to_s.gsub(/%CLASS%|[@%$?]/, cls)) if !rv && cls !~ /^::/ && scope.present? # Search inside scope
|
123
|
+
if cls.is_a?(::String) || cls.is_a?(::Symbol)
|
124
|
+
rv, cls = perform_initial_class_search(cls, only_in_scope)
|
125
|
+
rv = search_class_inside_scope(rv, cls, scope) # Search inside scope
|
131
126
|
rv || raise(NameError.new("", cls))
|
132
127
|
else
|
133
128
|
cls.is_a?(::Class) ? cls : cls.class
|
@@ -139,18 +134,60 @@ module Lazier
|
|
139
134
|
# @param message [String|NilClass] An optional message (see return value).
|
140
135
|
# @param precision [Fixnum] The precision for the message (see return value)..
|
141
136
|
# @param block [Proc] The block to evaluate.
|
142
|
-
# @return [Float|String] If a `message` is provided, then the message itself plus the duration under parenthesis will be returned,
|
137
|
+
# @return [Float|String] If a `message` is provided, then the message itself plus the duration under parenthesis will be returned,
|
138
|
+
# otherwise the duration alone as a number.
|
143
139
|
def self.benchmark(message = nil, precision = 0, &block)
|
144
140
|
rv = Benchmark.ms(&block)
|
145
|
-
message ? ("%s (%0.#{precision}f ms)"
|
141
|
+
message ? format("%s (%0.#{precision}f ms)", message, rv) : rv
|
146
142
|
end
|
147
143
|
|
148
144
|
private
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
145
|
+
|
146
|
+
# Removes existing `compact` and `compact!` methods from the Hash class.
|
147
|
+
def self.clean_hash_compact
|
148
|
+
::Hash.class_eval do
|
149
|
+
begin
|
150
|
+
remove_method(:compact)
|
151
|
+
remove_method(:compact!)
|
152
|
+
rescue
|
153
|
+
nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Performs the initial search to find a class.
|
159
|
+
# @param cls [Symbol|String|Object] If a `String` or a `Symbol` or a `Class`, then it will be the class to instantiate.
|
160
|
+
# @param only_in_scope [Boolean] If only try to instantiate the class in the scope.
|
161
|
+
# @return [Array] The found class (if any) and the sanitized name.
|
162
|
+
def self.perform_initial_class_search(cls, only_in_scope)
|
163
|
+
rv = nil
|
164
|
+
cls.to_s.camelize
|
165
|
+
|
166
|
+
if only_in_scope
|
167
|
+
cls.gsub!(/^::/, "") # Mark only search only inside scope
|
168
|
+
else
|
169
|
+
rv = search_class(cls) # Search outside scope
|
155
170
|
end
|
171
|
+
|
172
|
+
[rv, cls]
|
173
|
+
end
|
174
|
+
|
175
|
+
# Tries to search a class.
|
176
|
+
#
|
177
|
+
# @param cls [String] The class to search.
|
178
|
+
# @return [Class] The instantiated class.
|
179
|
+
def self.search_class(cls)
|
180
|
+
cls.constantize rescue nil
|
181
|
+
end
|
182
|
+
|
183
|
+
# Finds a class inside a specific scope.
|
184
|
+
#
|
185
|
+
# @param current [Class] The class found outside the scope.
|
186
|
+
# @param cls [String] The class to search.
|
187
|
+
# @param scope [String] The scope to search the class into.
|
188
|
+
# @return [Class] The found class.
|
189
|
+
def self.search_class_inside_scope(current, cls, scope)
|
190
|
+
cls = cls.ensure_string
|
191
|
+
!current && cls !~ /^::/ && scope.present? ? search_class(scope.to_s.gsub(/%CLASS%|[@%$?]/, cls)) : current
|
192
|
+
end
|
156
193
|
end
|
data/lib/lazier/boolean.rb
CHANGED
data/lib/lazier/configuration.rb
CHANGED
@@ -30,7 +30,7 @@ module Lazier
|
|
30
30
|
def self.property(property_name, options = {})
|
31
31
|
super(property_name, options)
|
32
32
|
|
33
|
-
if options[:readonly]
|
33
|
+
if options[:readonly]
|
34
34
|
class_eval <<-ACCESSOR
|
35
35
|
def #{property_name}=(_)
|
36
36
|
raise ArgumentError.new(@lazier_i18n.configuration.readonly("#{property_name}", "#{name}"))
|
@@ -40,25 +40,26 @@ module Lazier
|
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
43
|
-
# Checks if a property exists.
|
44
|
-
#
|
45
|
-
# @param property [String|Symbol] The property to check.
|
46
|
-
def assert_property_exists!(property)
|
47
|
-
raise ArgumentError.new(@lazier_i18n.configuration.not_found(property, self.class.name)) if !self.class.property?(property)
|
48
|
-
end
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
44
|
+
# Checks if a property exists.
|
45
|
+
#
|
46
|
+
# @param property [String|Symbol] The property to check.
|
47
|
+
def assert_property_exists!(property)
|
48
|
+
raise(ArgumentError, @lazier_i18n.configuration.not_found(property, self.class.name)) unless self.class.property?(property)
|
49
|
+
end
|
56
50
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
51
|
+
# Checks if a property has been set.
|
52
|
+
#
|
53
|
+
# @param property [String|Symbol] The property to check.
|
54
|
+
def assert_property_set!(property)
|
55
|
+
raise(ArgumentError, @lazier_i18n.configuration.required(property, self.class.name)) if send(property).is_a?(NilClass)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Checks if a property is required.
|
59
|
+
#
|
60
|
+
# @param property [String|Symbol] The property to check.
|
61
|
+
def assert_property_required!(property, value)
|
62
|
+
raise(ArgumentError, @lazier_i18n.configuration.required(property, self.class.name)) if self.class.required?(property) && value.is_a?(NilClass)
|
63
|
+
end
|
63
64
|
end
|
64
|
-
end
|
65
|
+
end
|
data/lib/lazier/datetime.rb
CHANGED
@@ -91,7 +91,7 @@ module Lazier
|
|
91
91
|
# @param with_offset [Boolean] If to include offset into the representation.
|
92
92
|
# @return [String] A string representation which can be used for searches.
|
93
93
|
def parameterize_zone(tz, with_offset = true)
|
94
|
-
::ActiveSupport::TimeZone
|
94
|
+
::ActiveSupport::TimeZone.parameterize_zone(tz, with_offset)
|
95
95
|
end
|
96
96
|
|
97
97
|
# Finds a parameterized timezone.
|
@@ -102,7 +102,7 @@ module Lazier
|
|
102
102
|
# @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
|
103
103
|
# @return [String|TimeZone] The found timezone or `nil` if the zone is not valid.
|
104
104
|
def unparameterize_zone(tz, as_string = false, dst_label = nil)
|
105
|
-
::ActiveSupport::TimeZone
|
105
|
+
::ActiveSupport::TimeZone.unparameterize_zone(tz, as_string, dst_label)
|
106
106
|
end
|
107
107
|
|
108
108
|
# Returns an offset in rational value.
|
@@ -119,13 +119,13 @@ module Lazier
|
|
119
119
|
# @param year [Fixnum] The year to compute the date for. Defaults to the current year.
|
120
120
|
# @return [Date] The Easter date for the year.
|
121
121
|
def easter(year = nil)
|
122
|
-
year = ::Date.today.year
|
122
|
+
year = ::Date.today.year unless year.is_integer?
|
123
123
|
|
124
124
|
# Compute using Anonymous Gregorian Algorithm: http://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm
|
125
125
|
data = easter_start(year)
|
126
|
-
data =
|
127
|
-
data =
|
128
|
-
data =
|
126
|
+
data = easter_divide(data)
|
127
|
+
data = easter_aggregate(year, data)
|
128
|
+
data = easter_prepare(year, data)
|
129
129
|
day, month = easter_end(data)
|
130
130
|
|
131
131
|
::Date.civil(year, month, day)
|
@@ -146,61 +146,66 @@ module Lazier
|
|
146
146
|
# @param value [String] The value to check.
|
147
147
|
# @param format [String] The format to check the value against.
|
148
148
|
# @return [Boolean] `true` if the value is valid against the format, `false` otherwise.
|
149
|
-
def
|
150
|
-
|
149
|
+
def valid?(value, format = "%F %T")
|
150
|
+
::DateTime.strptime(value, custom_format(format))
|
151
|
+
true
|
152
|
+
rescue
|
153
|
+
false
|
151
154
|
end
|
155
|
+
alias_method :is_valid?, :valid?
|
152
156
|
|
153
157
|
private
|
154
|
-
# Part one of Easter calculation.
|
155
|
-
#
|
156
|
-
# @param year [Fixnum] The year to compute the date for.
|
157
|
-
# @return [Array] Partial variables for #easter_part_1.
|
158
|
-
def easter_start(year)
|
159
|
-
[year % 19, (year / 100.0).floor, year % 100]
|
160
|
-
end
|
161
158
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
b - (b / 4.0).floor - ((b - ((b + 8) / 25.0).floor + 1) / 3.0).floor,
|
170
|
-
b % 4,
|
171
|
-
(c / 4.0).floor,
|
172
|
-
c % 4
|
173
|
-
]
|
174
|
-
end
|
159
|
+
# Part one of Easter calculation.
|
160
|
+
#
|
161
|
+
# @param year [Fixnum] The year to compute the date for.
|
162
|
+
# @return [Array] Partial variables for #easter_divide.
|
163
|
+
def easter_start(year)
|
164
|
+
[year % 19, (year / 100.0).floor, year % 100]
|
165
|
+
end
|
175
166
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
167
|
+
# Part two of Easter calculation.
|
168
|
+
# @param data [Fixnum] Partial variables from #easter_start.
|
169
|
+
# @return [Array] Partial variables for #easter_aggregate.
|
170
|
+
def easter_divide(data)
|
171
|
+
_, b, c = data
|
172
|
+
|
173
|
+
[
|
174
|
+
b - (b / 4.0).floor - ((b - ((b + 8) / 25.0).floor + 1) / 3.0).floor,
|
175
|
+
b % 4,
|
176
|
+
(c / 4.0).floor,
|
177
|
+
c % 4
|
178
|
+
]
|
179
|
+
end
|
186
180
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
181
|
+
# Part three of Easter calculation.
|
182
|
+
#
|
183
|
+
# @param data [Fixnum] Partial variables from #easter_divide.
|
184
|
+
# @return [Array] Partial variables for #easter_prepare.
|
185
|
+
def easter_aggregate(year, data)
|
186
|
+
a = year % 19
|
187
|
+
x, e, i, k = data
|
188
|
+
h = ((19 * a) + x + 15) % 30
|
189
|
+
[h, (32 + (2 * e) + (2 * i) - h - k) % 7]
|
190
|
+
end
|
195
191
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
192
|
+
# Part four of Easter calculation
|
193
|
+
# @param data [Arrays] Partial variables from #easter_aggregate.
|
194
|
+
# @return [Array] Partial variables for #easter_end.
|
195
|
+
def easter_prepare(year, data)
|
196
|
+
a = year % 19
|
197
|
+
h, l = data
|
198
|
+
[h, l, ((a + (11 * h) + (22 * l)) / 451.0).floor]
|
199
|
+
end
|
200
|
+
|
201
|
+
# Final part of Easter calculation.
|
202
|
+
#
|
203
|
+
# @param data [Fixnum] Variable from #easter_prepare.
|
204
|
+
# @return [Array] Day and month of Easter day.
|
205
|
+
def easter_end(data)
|
206
|
+
h, l, m = data
|
207
|
+
[((h + l - (7 * m) + 114) % 31) + 1, ((h + l - (7 * m) + 114) / 31.0).floor]
|
208
|
+
end
|
204
209
|
end
|
205
210
|
|
206
211
|
# Returns the UTC::Time representation of the current datetime.
|
@@ -236,7 +241,7 @@ module Lazier
|
|
236
241
|
# @param format [String] A format or a custom format name to use for formatting.
|
237
242
|
# @return [String] The formatted date.
|
238
243
|
def lstrftime(format = nil)
|
239
|
-
strftime(::DateTime.custom_format(format.to_s).gsub(/(?<!%)(%[ab])/i) {|mo| localize_time_component(mo) })
|
244
|
+
strftime(::DateTime.custom_format(format.to_s).gsub(/(?<!%)(%[ab])/i) { |mo| localize_time_component(mo) })
|
240
245
|
end
|
241
246
|
|
242
247
|
# Formats a datetime in the current timezone.
|
@@ -257,15 +262,16 @@ module Lazier
|
|
257
262
|
end
|
258
263
|
|
259
264
|
private
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
265
|
+
|
266
|
+
# Returns a component of the date in the current locale.
|
267
|
+
#
|
268
|
+
# @param component [String] The component to localize.
|
269
|
+
# @return [String] The localized component.
|
270
|
+
def localize_time_component(component)
|
271
|
+
type = {"%a" => :short_days, "%A" => :long_days, "%b" => :short_months, "%B" => :long_months}.fetch(component, "")
|
272
|
+
index = component =~ /%a/i ? wday : month - 1
|
273
|
+
::Lazier.settings.date_names[type][index]
|
274
|
+
end
|
269
275
|
end
|
270
276
|
|
271
277
|
# Extensions for timezone objects.
|
@@ -288,7 +294,7 @@ module Lazier
|
|
288
294
|
# @param colon [Boolean] If to put the colon in the output string.
|
289
295
|
# @return [String] The formatted offset.
|
290
296
|
def format_offset(offset, colon = true)
|
291
|
-
|
297
|
+
seconds_to_utc_offset(offset.is_a?(::Rational) ? (offset * 86_400).to_i : offset, colon)
|
292
298
|
end
|
293
299
|
|
294
300
|
# Find a zone by its name.
|
@@ -317,7 +323,9 @@ module Lazier
|
|
317
323
|
dst_label ||= "(DST)"
|
318
324
|
|
319
325
|
@zones_names ||= { "STANDARD" => ::ActiveSupport::TimeZone.all.map(&:to_s) }
|
320
|
-
@zones_names["DST[#{dst_label}]-STANDARD"] ||= ::ActiveSupport::TimeZone.all
|
326
|
+
@zones_names["DST[#{dst_label}]-STANDARD"] ||= ::ActiveSupport::TimeZone.all
|
327
|
+
.map { |zone| fetch_aliases(zone, dst_label) }.flatten.compact.uniq
|
328
|
+
.sort { |a, b| ::ActiveSupport::TimeZone.compare(a, b) } # Sort by name
|
321
329
|
|
322
330
|
@zones_names["#{with_dst ? "DST[#{dst_label}]-" : ""}STANDARD"]
|
323
331
|
end
|
@@ -332,10 +340,11 @@ module Lazier
|
|
332
340
|
# @param with_offset [Boolean] If to include offset into the representation.
|
333
341
|
# @return [String] A string representation which can be used for searches.
|
334
342
|
def parameterize_zone(tz, with_offset = true)
|
335
|
-
tz = tz.to_s
|
343
|
+
tz = tz.to_s unless tz.is_a?(::String)
|
344
|
+
mo = /^(\([a-z]+([+-])(\d{2})(:?)(\d{2})\)\s(.+))$/i.match(tz)
|
336
345
|
|
337
|
-
if
|
338
|
-
with_offset ? "#{
|
346
|
+
if mo
|
347
|
+
with_offset ? "#{mo[2]}#{mo[3]}#{mo[5]}@#{mo[6].to_s.parameterize}" : mo[6].to_s.parameterize
|
339
348
|
elsif !with_offset then
|
340
349
|
tz.gsub(/^([+-]?(\d{2})(:?)(\d{2})@)/, "")
|
341
350
|
else
|
@@ -352,17 +361,13 @@ module Lazier
|
|
352
361
|
# @return [String|TimeZone] The found timezone or `nil` if the zone is not valid.
|
353
362
|
def unparameterize_zone(tz, as_string = false, dst_label = nil)
|
354
363
|
tz = parameterize_zone(tz, false)
|
355
|
-
|
356
|
-
|
357
|
-
rv = catch(:zone) do
|
358
|
-
list_all(true, dst_label).each do |zone|
|
359
|
-
throw(:zone, zone) if parameterize_zone(zone, false) =~ matcher
|
360
|
-
end
|
364
|
+
rv = find_parameterized_zone(dst_label, /(#{Regexp.quote(tz)})$/)
|
361
365
|
|
366
|
+
if rv
|
367
|
+
as_string ? rv : find(rv, dst_label)
|
368
|
+
else
|
362
369
|
nil
|
363
370
|
end
|
364
|
-
|
365
|
-
rv ? (as_string ? rv : self.find(rv, dst_label)) : nil
|
366
371
|
end
|
367
372
|
|
368
373
|
# Compares two timezones. They are sorted by the location name.
|
@@ -377,17 +382,33 @@ module Lazier
|
|
377
382
|
end
|
378
383
|
|
379
384
|
private
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
385
|
+
|
386
|
+
# Returns a list of aliases for a given time zone.
|
387
|
+
#
|
388
|
+
# @param zone [ActiveSupport::TimeZone] The zone.
|
389
|
+
# @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
|
390
|
+
def fetch_aliases(zone, dst_label = "(DST)")
|
391
|
+
matcher = /(#{Regexp.quote(dst_label)})$/
|
392
|
+
|
393
|
+
zone.aliases.map { |zone_alias|
|
394
|
+
[zone.to_str(zone_alias), (zone.uses_dst? && zone_alias !~ matcher) ? zone.to_str_with_dst(dst_label, nil, zone_alias) : nil]
|
395
|
+
}
|
396
|
+
end
|
397
|
+
|
398
|
+
# Finds a parameterized timezone.
|
399
|
+
#
|
400
|
+
# @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
|
401
|
+
# @param matcher [Regexp] The expression to match.
|
402
|
+
# @return [TimeZone] The found timezone or `nil` if the zone is not valid.
|
403
|
+
def find_parameterized_zone(dst_label, matcher)
|
404
|
+
catch(:zone) do
|
405
|
+
list_all(true, dst_label).each do |zone|
|
406
|
+
throw(:zone, zone) if parameterize_zone(zone, false) =~ matcher
|
407
|
+
end
|
408
|
+
|
409
|
+
nil
|
390
410
|
end
|
411
|
+
end
|
391
412
|
end
|
392
413
|
|
393
414
|
# Returns a list of valid aliases (city names) for this timezone (basing on offset).
|
@@ -441,8 +462,8 @@ module Lazier
|
|
441
462
|
northern_summer = ::DateTime.civil(year, 7, 15).utc # This is a representation of a summer period in the Northern Hemisphere.
|
442
463
|
southern_summer = ::DateTime.civil(year, 1, 15).utc # This is a representation of a summer period in the Southern Hemisphere.
|
443
464
|
|
444
|
-
period =
|
445
|
-
period =
|
465
|
+
period = period_for_utc(northern_summer)
|
466
|
+
period = period_for_utc(southern_summer) unless period.dst?
|
446
467
|
period.dst? ? period : nil
|
447
468
|
end
|
448
469
|
|
@@ -451,7 +472,7 @@ module Lazier
|
|
451
472
|
# @param reference [Object] The date or year to check. Defaults to the current year.
|
452
473
|
# @return [Boolean] `true` if the zone uses DST for that date or year, `false` otherwise.
|
453
474
|
def uses_dst?(reference = nil)
|
454
|
-
if reference.respond_to?(:year) && reference.respond_to?(:utc)
|
475
|
+
if reference.respond_to?(:year) && reference.respond_to?(:utc) # This is a date like object
|
455
476
|
dst_period(reference.year).present? && period_for_utc(reference.utc).dst?
|
456
477
|
else
|
457
478
|
dst_period(reference).present?
|
@@ -495,7 +516,7 @@ module Lazier
|
|
495
516
|
# @param colon [Boolean] If to put the colon in the output string.
|
496
517
|
# @return [String] The name for this zone.
|
497
518
|
def to_str(name = nil, colon = true)
|
498
|
-
"(GMT#{
|
519
|
+
"(GMT#{formatted_offset(colon)}) #{name || current_alias}"
|
499
520
|
end
|
500
521
|
|
501
522
|
# Returns a string representation for this zone with Daylight Saving Time (DST) active.
|
@@ -505,7 +526,7 @@ module Lazier
|
|
505
526
|
# @param name [String] The name to use for this zone. Defaults to the zone name.
|
506
527
|
# @return [String] The string representation for the zone with DST or `nil`, if the timezone doesn't use DST for that year.
|
507
528
|
def to_str_with_dst(dst_label = nil, year = nil, name = nil)
|
508
|
-
|
529
|
+
uses_dst?(year) ? "(GMT#{self.class.seconds_to_utc_offset(dst_period(year).utc_total_offset)}) #{name || current_alias} #{dst_label || "(DST)"}" : nil
|
509
530
|
end
|
510
531
|
|
511
532
|
# Returns a parameterized string representation for this zone.
|
@@ -529,14 +550,19 @@ module Lazier
|
|
529
550
|
end
|
530
551
|
|
531
552
|
private
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
553
|
+
|
554
|
+
# Formats a time zone alias.
|
555
|
+
#
|
556
|
+
# @param name [String] The zone name.
|
557
|
+
# @param zone [String] The zone.
|
558
|
+
# @param reference [String] The main name for the zone.
|
559
|
+
# @return [String|nil] The formatted alias.
|
560
|
+
def format_alias(name, zone, reference)
|
561
|
+
if zone.gsub("_", " ") == reference
|
562
|
+
["International Date Line West", "UTC"].include?(name) || name.include?("(US & Canada)") ? name : reference.gsub(/\/.*/, "/#{name}")
|
563
|
+
else
|
564
|
+
nil
|
540
565
|
end
|
566
|
+
end
|
541
567
|
end
|
542
|
-
end
|
568
|
+
end
|