lazier 3.5.7 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.travis-gemfile +5 -4
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +65 -8
  5. data/Gemfile +9 -8
  6. data/README.md +4 -0
  7. data/doc/Lazier.html +178 -110
  8. data/doc/Lazier/Boolean.html +7 -7
  9. data/doc/Lazier/Configuration.html +24 -50
  10. data/doc/Lazier/DateTime.html +50 -305
  11. data/doc/Lazier/DateTime/ClassMethods.html +116 -806
  12. data/doc/Lazier/Exceptions.html +2 -2
  13. data/doc/Lazier/Exceptions/Debug.html +1 -1
  14. data/doc/Lazier/Exceptions/MissingTranslation.html +18 -14
  15. data/doc/Lazier/Exceptions/TranslationExceptionHandler.html +213 -0
  16. data/doc/Lazier/Hash.html +19 -155
  17. data/doc/Lazier/I18n.html +1735 -230
  18. data/doc/Lazier/Math.html +1 -1
  19. data/doc/Lazier/Math/ClassMethods.html +13 -13
  20. data/doc/Lazier/Object.html +353 -339
  21. data/doc/Lazier/Pathname.html +4 -4
  22. data/doc/Lazier/Settings.html +150 -304
  23. data/doc/Lazier/String.html +39 -199
  24. data/doc/Lazier/TimeZone.html +244 -746
  25. data/doc/Lazier/TimeZone/ClassMethods.html +109 -127
  26. data/doc/Lazier/Version.html +4 -4
  27. data/doc/_index.html +15 -15
  28. data/doc/class_list.html +1 -1
  29. data/doc/file.README.html +5 -1
  30. data/doc/index.html +5 -1
  31. data/doc/method_list.html +97 -169
  32. data/doc/top-level-namespace.html +1 -1
  33. data/lazier.gemspec +9 -6
  34. data/lib/lazier.rb +41 -50
  35. data/lib/lazier/boolean.rb +0 -1
  36. data/lib/lazier/configuration.rb +26 -28
  37. data/lib/lazier/datetime.rb +33 -127
  38. data/lib/lazier/exceptions.rb +14 -6
  39. data/lib/lazier/hash.rb +7 -15
  40. data/lib/lazier/i18n.rb +130 -48
  41. data/lib/lazier/math.rb +6 -7
  42. data/lib/lazier/object.rb +79 -97
  43. data/lib/lazier/pathname.rb +0 -1
  44. data/lib/lazier/settings.rb +12 -25
  45. data/lib/lazier/string.rb +17 -38
  46. data/lib/lazier/timezone.rb +168 -164
  47. data/lib/lazier/version.rb +3 -4
  48. data/locales/en.yml +52 -51
  49. data/locales/it.yml +51 -50
  50. data/spec/coverage_helper.rb +0 -1
  51. data/spec/lazier/boolean_spec.rb +2 -3
  52. data/spec/lazier/configuration_spec.rb +3 -5
  53. data/spec/lazier/datetime_spec.rb +34 -95
  54. data/spec/lazier/exceptions_spec.rb +25 -0
  55. data/spec/lazier/hash_spec.rb +0 -21
  56. data/spec/lazier/i18n_spec.rb +135 -51
  57. data/spec/lazier/math_spec.rb +0 -1
  58. data/spec/lazier/object_spec.rb +105 -100
  59. data/spec/lazier/pathname_spec.rb +0 -1
  60. data/spec/lazier/settings_spec.rb +25 -28
  61. data/spec/lazier/string_spec.rb +7 -20
  62. data/spec/lazier/timezone_spec.rb +101 -87
  63. data/spec/lazier_spec.rb +25 -8
  64. data/spec/spec_helper.rb +3 -2
  65. metadata +15 -44
  66. data/doc/Lazier/Localizer.html +0 -545
  67. data/lib/lazier/localizer.rb +0 -41
  68. data/spec/lazier/localizer_spec.rb +0 -45
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # This file is part of the lazier gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
3
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # This file is part of the lazier gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
3
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
@@ -18,12 +17,7 @@ module Lazier
18
17
  # @attribute [r] i18n
19
18
  # @return [R18n::Translation] The translation object.
20
19
  class Settings
21
- attr_reader :format_number
22
- attr_reader :boolean_names
23
- attr_reader :date_names
24
- attr_reader :date_formats
25
-
26
- include Lazier::I18n
20
+ attr_reader :format_number, :boolean_names, :date_names, :date_formats, :i18n
27
21
 
28
22
  # Returns the singleton instance of the settings.
29
23
  #
@@ -31,12 +25,12 @@ module Lazier
31
25
  # @return [Settings] The singleton instance of the settings.
32
26
  def self.instance(force = false)
33
27
  @instance = nil if force
34
- @instance ||= ::Lazier::Settings.new
28
+ @instance ||= new
35
29
  end
36
30
 
37
31
  # Initializes a new settings object.
38
32
  def initialize
39
- i18n_setup(:lazier, ::File.absolute_path(::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/"))
33
+ @i18n = Lazier::I18n.instance
40
34
  setup
41
35
  end
42
36
 
@@ -48,15 +42,6 @@ module Lazier
48
42
  setup_date_names
49
43
  end
50
44
 
51
- # Set the current locale for messages.
52
- #
53
- # @param locale [String] The new locale. Default is the current system locale.
54
- # @return [R18n::Translation] The new translation object.
55
- def i18n=(locale)
56
- super(locale)
57
- setup
58
- end
59
-
60
45
  # Setups formatters for a number.
61
46
  # @see Object#format_number
62
47
  #
@@ -65,7 +50,7 @@ module Lazier
65
50
  # @param add_string [String] The string to append to the number.
66
51
  # @param k_separator [String] The string to use as thousands separator.
67
52
  # @return [Hash] The new formatters.
68
- def setup_format_number(precision = 2, decimal_separator = ".", add_string = nil, k_separator = ",")
53
+ def setup_format_number(precision: 2, decimal_separator: ".", add_string: nil, k_separator: ",")
69
54
  @format_number = ::HashWithIndifferentAccess.new(
70
55
  precision: precision, decimal_separator: decimal_separator, add_string: add_string, k_separator: k_separator
71
56
  )
@@ -77,8 +62,9 @@ module Lazier
77
62
  # @param true_name [String] The string representation of `true`. Defaults to `Yes`.
78
63
  # @param false_name [String] The string representation of `false`. Defaults to `No`.
79
64
  # @return [Hash] The new representations.
80
- def setup_boolean_names(true_name = nil, false_name = nil)
81
- @boolean_names = {true => true_name || i18n.boolean[0], false => false_name || i18n.boolean[1]}
65
+ def setup_boolean_names(true_name: nil, false_name: nil)
66
+ names = i18n.translate("boolean")
67
+ @boolean_names = {true => true_name || names[0], false => false_name || names[1]}
82
68
  end
83
69
 
84
70
  # Setups custom formats for dates and times.
@@ -90,7 +76,8 @@ module Lazier
90
76
  def setup_date_formats(formats = nil, replace = false)
91
77
  @date_formats = HashWithIndifferentAccess.new if replace || !@date_formats
92
78
 
93
- @date_formats.merge!(formats.ensure_hash(nil, {ct_date: "%Y-%m-%d", ct_time: "%H:%M:%S", ct_date_time: "%F %T", ct_iso_8601: "%FT%T%z" }))
79
+ formats = {ct_date: "%Y-%m-%d", ct_time: "%H:%M:%S", ct_date_time: "%F %T", ct_iso_8601: "%FT%T%z" } unless formats.is_a?(::Hash)
80
+ @date_formats.merge!(formats)
94
81
  ::Time::DATE_FORMATS.merge!(@date_formats)
95
82
 
96
83
  @date_formats
@@ -106,15 +93,15 @@ module Lazier
106
93
  # @param long_days [Array] The string representation of days.
107
94
  # @param short_days [Array] The abbreviated string representation of days.
108
95
  # @return [Hash] The new representations.
109
- def setup_date_names(long_months = nil, short_months = nil, long_days = nil, short_days = nil)
110
- definitions = i18n.date
96
+ def setup_date_names(long_months: nil, short_months: nil, long_days: nil, short_days: nil)
97
+ definitions = i18n.translate("date").ensure_access(:dotted)
111
98
 
112
99
  @date_names = {
113
100
  long_months: long_months.ensure(definitions.long_months),
114
101
  short_months: short_months.ensure(definitions.short_months),
115
102
  long_days: long_days.ensure(definitions.long_days),
116
103
  short_days: short_days.ensure(definitions.short_days)
117
- }.with_indifferent_access
104
+ }.ensure_access(:indifferent, :dotted)
118
105
  end
119
106
  end
120
107
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # This file is part of the lazier gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
3
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
@@ -9,18 +8,6 @@ module Lazier
9
8
  module String
10
9
  extend ::ActiveSupport::Concern
11
10
 
12
- # Removes accents from the string, normalizing to the normal letter.
13
- #
14
- # ```ruby
15
- # "èòàù".remove_accents
16
- # # => "eoau"
17
- # ```
18
- #
19
- # @return The string with all accents removed.
20
- def remove_accents
21
- silence_warnings { mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, "").to_s }
22
- end
23
-
24
11
  # Makes sure the string only contains valid UTF-8 sequences.
25
12
  #
26
13
  # @param replacement [String] The string to use to replace invalid sequences.
@@ -30,27 +17,6 @@ module Lazier
30
17
  encode("utf-16", invalid: :replace, undef: :replace, replace: replacement).encode("utf-8")
31
18
  end
32
19
 
33
- # Returns the tagged version of a string.
34
- #
35
- # The string is downcased and spaces are substituted with `-`.
36
- #
37
- # ```ruby
38
- # "ABC cde".untitleize
39
- # # => "abc-cde"
40
- # ```
41
- #
42
- # @return [String] The untitleized version of the string.
43
- def untitleize
44
- downcase.gsub(" ", "-")
45
- end
46
-
47
- # Returns the string with all `&amp;` replaced with `&`.
48
- #
49
- # @return [String] The string with all `&amp;` replaced with `&`.
50
- def replace_ampersands
51
- gsub(/&amp;(\S+);/, "&\\1;")
52
- end
53
-
54
20
  # Returns the string itself for use in form helpers.
55
21
  #
56
22
  # @return [String] The string itself.
@@ -62,15 +28,28 @@ module Lazier
62
28
  #
63
29
  # @param no_blanks [Boolean] If filter out blank tokens.
64
30
  # @param strip [Boolean] If strip single tokens.
65
- # @param uniq [Boolean] If return uniques elements.
31
+ # @param no_duplicates [Boolean] If return uniques elements.
66
32
  # @param pattern [String|Regexp] The pattern to use.
33
+ # @param presence_method [Symbol] The method to use to check if a token is present or not.
67
34
  # @return [Array] An array of tokens.
68
- def split_tokens(no_blanks = true, strip = true, uniq = false, pattern = /\s*,\s*/)
35
+ def tokenize(no_blanks: true, strip: true, no_duplicates: false, pattern: /\s*,\s*/, presence_method: :present?)
69
36
  rv = split(pattern)
70
37
  rv.map!(&:strip) if strip
71
- rv.select!(&:present?) if no_blanks
72
- rv.uniq! if uniq
38
+ rv.select!(&presence_method) if no_blanks
39
+ rv.uniq! if no_duplicates
73
40
  rv
74
41
  end
42
+
43
+ # Removes accents from the string, normalizing to the normal letter.
44
+ #
45
+ # ```ruby
46
+ # "èòàù".remove_accents
47
+ # # => "eoau"
48
+ # ```
49
+ #
50
+ # @return The string with all accents removed.
51
+ def remove_accents
52
+ ::I18n.transliterate(self)
53
+ end
75
54
  end
76
55
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  #
3
2
  # This file is part of the lazier gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
3
  # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
@@ -9,14 +8,28 @@ module Lazier
9
8
  module TimeZone
10
9
  extend ::ActiveSupport::Concern
11
10
 
11
+ # Pattern for a parameterized timezone.
12
+ ALREADY_PARAMETERIZED = /^[+-]\d{4}@[a-z-]+/
13
+
14
+ # Pattern for a unparameterized timezone.
15
+ PARAMETERIZER = /^(
16
+ \(
17
+ [a-z]+ # UTC Label
18
+ (?<offset>([+-])(\d{2})(:?)(\d{2}))
19
+ \)
20
+ \s
21
+ (?<label>.+)
22
+ )$/xi
23
+
12
24
  # General methods.
13
25
  module ClassMethods
26
+ # Expression to parameterize a zone
14
27
  # Returns an offset in rational value.
15
28
  #
16
29
  # @param offset [Fixnum] The offset to convert.
17
30
  # @return [Rational] The converted offset.
18
31
  def rationalize_offset(offset)
19
- ::TZInfo::OffsetRationals.rational_for_offset(offset.is_a?(::Fixnum) ? offset : offset.offset)
32
+ ::TZInfo::OffsetRationals.rational_for_offset(offset)
20
33
  end
21
34
 
22
35
  # Returns a +HH:MM formatted representation of the offset.
@@ -31,37 +44,30 @@ module Lazier
31
44
  # Find a zone by its name.
32
45
  #
33
46
  # @param name [String] The zone name.
34
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
47
+ # @param dst_label [String] Label for the DST indication. Defaults to ` (DST)`.
35
48
  # @return [TimeZone] A timezone or `nil` if no zone was found.
36
- def find(name, dst_label = nil)
37
- catch(:zone) do
38
- ::ActiveSupport::TimeZone.all.each do |zone|
39
- zone.aliases.each do |zone_alias|
40
- if [zone.to_str(zone_alias), zone.to_str_with_dst(dst_label, nil, zone_alias)].include?(name)
41
- zone.current_alias = zone_alias
42
- throw(:zone, zone)
43
- end
44
- end
45
- end
46
-
47
- nil
48
- end
49
+ def find(name, dst_label = " (DST)")
50
+ list(true, dst_label: dst_label, as_hash: true)[name]
49
51
  end
50
52
 
51
53
  # Returns a list of names of all timezones.
52
54
  #
53
55
  # @param with_dst [Boolean] If include DST version of the zones.
54
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
55
- # @return [Array] A list of names of timezones.
56
- def list_all(with_dst = true, dst_label = nil)
57
- dst_label ||= "(DST)"
58
-
59
- @zones_names ||= { "STANDARD" => ::ActiveSupport::TimeZone.all.map(&:to_s) }
60
- @zones_names["DST[#{dst_label}]-STANDARD"] ||= ::ActiveSupport::TimeZone.all
61
- .map { |zone| fetch_aliases(zone, dst_label) }.flatten.compact.uniq
62
- .sort { |a, b| ::ActiveSupport::TimeZone.compare(a, b) } # Sort by name
56
+ # @param parameterized [Boolean] If parameterize zones.
57
+ # @param dst_label [String] Label for the DST indication. Defaults to ` (DST)`.
58
+ # @param as_hash [Hash] If return an hash.
59
+ # @return [Array|Hash] A list of names of timezones or a hash with labels and timezones as keys.
60
+ def list(with_dst = true, dst_label: " (DST)", parameterized: false, sort_by_name: true, as_hash: false)
61
+ dst_label = nil unless with_dst
62
+ key = [dst_label, sort_by_name, as_hash, parameterized].join(":")
63
+ @zones_names ||= {}
64
+
65
+ unless @zones_names[key]
66
+ all = ::ActiveSupport::TimeZone.all
67
+ @zones_names[key] = send("finalize_list_as_#{as_hash ? "hash" : "list"}", all, dst_label, parameterized, sort_by_name)
68
+ end
63
69
 
64
- @zones_names["#{with_dst ? "DST[#{dst_label}]-" : ""}STANDARD"]
70
+ @zones_names[key]
65
71
  end
66
72
 
67
73
  # Returns a string representation of a timezone.
@@ -70,17 +76,17 @@ module Lazier
70
76
  # DateTime.parameterize_zone(ActiveSupport::TimeZone["Pacific Time (US & Canada)"])
71
77
  # # => "-0800@pacific-time-us-canada"
72
78
  # ```
73
- # @param tz [TimeZone] The zone to represent.
79
+ # @param tz [TimeZone|String] The zone to represent.
74
80
  # @param with_offset [Boolean] If to include offset into the representation.
75
81
  # @return [String] A string representation which can be used for searches.
76
- def parameterize_zone(tz, with_offset = true)
77
- tz = tz.to_s unless tz.is_a?(::String)
78
- mo = /^(\([a-z]+([+-])(\d{2})(:?)(\d{2})\)\s(.+))$/i.match(tz)
79
-
80
- if mo
81
- with_offset ? "#{mo[2]}#{mo[3]}#{mo[5]}@#{mo[6].to_s.parameterize}" : mo[6].to_s.parameterize
82
- elsif !with_offset then
83
- tz.gsub(/^([+-]?(\d{2})(:?)(\d{2})@)/, "")
82
+ def parameterize(tz, with_offset = true)
83
+ tz = tz.to_str unless tz.is_a?(::String)
84
+
85
+ if tz =~ ::Lazier::TimeZone::ALREADY_PARAMETERIZED
86
+ tz
87
+ elsif tz =~ ::Lazier::TimeZone::PARAMETERIZER
88
+ mo = $LAST_MATCH_INFO
89
+ [(with_offset ? mo[:offset].gsub(":", "") : nil), mo[:label].parameterize].compact.join("@")
84
90
  else
85
91
  tz.parameterize
86
92
  end
@@ -90,18 +96,11 @@ module Lazier
90
96
  # @see DateTime#parameterize_zone
91
97
  #
92
98
  # @param tz [String] The zone to unparameterize.
93
- # @param as_string [Boolean] If return just the zone name.
94
99
  # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
95
- # @return [String|TimeZone] The found timezone or `nil` if the zone is not valid.
96
- def unparameterize_zone(tz, as_string = false, dst_label = nil)
97
- tz = parameterize_zone(tz, false)
98
- rv = find_parameterized_zone(dst_label, /(#{Regexp.quote(tz)})$/)
99
-
100
- if rv
101
- as_string ? rv : find(rv, dst_label)
102
- else
103
- nil
104
- end
100
+ # @return [TimeZone] The found timezone or `nil` if the zone is not valid.
101
+ def unparameterize(tz, dst_label = " (DST)")
102
+ tz = parameterize(tz)
103
+ list(true, dst_label: dst_label, parameterized: true, as_hash: true)[tz]
105
104
  end
106
105
 
107
106
  # Compares two timezones. They are sorted by the location name.
@@ -117,31 +116,35 @@ module Lazier
117
116
 
118
117
  private
119
118
 
120
- # Returns a list of aliases for a given time zone.
121
- #
122
- # @param zone [ActiveSupport::TimeZone] The zone.
123
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
124
- def fetch_aliases(zone, dst_label = "(DST)")
125
- matcher = /(#{Regexp.quote(dst_label)})$/
126
-
119
+ # :nodoc:
120
+ def fetch_aliases(zone, dst_label = "(DST)", parameterized = false)
127
121
  zone.aliases.map { |zone_alias|
128
- [zone.to_str(zone_alias), (zone.uses_dst? && zone_alias !~ matcher) ? zone.to_str_with_dst(dst_label, nil, zone_alias) : nil]
129
- }
122
+ [
123
+ zone.to_str(false, label: zone_alias, parameterized: parameterized),
124
+ (zone.uses_dst? && dst_label) ? zone.to_str(true, label: zone_alias, dst_label: dst_label, parameterized: parameterized) : nil
125
+ ]
126
+ }.flatten.uniq.compact
130
127
  end
131
128
 
132
- # Finds a parameterized timezone.
133
- #
134
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
135
- # @param matcher [Regexp] The expression to match.
136
- # @return [String] The found timezone or `nil` if the zone is not valid.
137
- def find_parameterized_zone(dst_label, matcher)
138
- catch(:zone) do
139
- list_all(true, dst_label).each do |zone|
140
- throw(:zone, zone) if parameterize_zone(zone, false) =~ matcher
141
- end
142
-
143
- nil
144
- end
129
+ # :nodoc:
130
+ def finalize_list_as_list(all, dst_label, parameterized, sort_by_name)
131
+ rv = all.map { |zone|
132
+ fetch_aliases(zone, dst_label, parameterized)
133
+ }.flatten.uniq
134
+
135
+ sort_by_name ? rv.sort { |a, b| ::ActiveSupport::TimeZone.compare(a, b) } : rv
136
+ end
137
+
138
+ # :nodoc:
139
+ def finalize_list_as_hash(all, dst_label, parameterized, sort_by_name)
140
+ rv = all.reduce({}) { |accu, zone|
141
+ accu.merge(fetch_aliases(zone, dst_label, parameterized).reduce({}) { |a, e|
142
+ a[e] = zone
143
+ a
144
+ })
145
+ }
146
+
147
+ sort_by_name ? ::Hash[rv.sort { |a, b| ::ActiveSupport::TimeZone.compare(a[0], b[0]) }] : rv
145
148
  end
146
149
  end
147
150
 
@@ -158,150 +161,124 @@ module Lazier
158
161
  # @param date [DateTime] The date to consider. Defaults to now.
159
162
  # @return [Fixnum|Rational] The offset of this timezone.
160
163
  def current_offset(rational = false, date = nil)
161
- date ||= ::DateTime.now
162
- rv = (period_for_utc(date.utc).dst? ? dst_offset : offset)
163
- rational ? self.class.rationalize_offset(rv) : rv
164
+ date = (date || ::DateTime.current).in_time_zone
165
+ offset(rational: rational, dst: date.dst?, year: date.year)
164
166
  end
165
167
 
166
168
  # Returns the current alias for this timezone.
167
169
  #
168
170
  # @return [String] The current alias or the first alias of the current timezone.
169
171
  def current_alias
170
- if @current_alias
171
- @current_alias
172
- else
173
- identifier = tzinfo.identifier
172
+ identifier = name
174
173
 
175
- catch(:alias) do
176
- aliases.each do |a|
177
- throw(:alias, a) if a == identifier
178
- end
179
-
180
- aliases.first
174
+ catch(:alias) do
175
+ aliases.each do |a|
176
+ throw(:alias, a) if a == identifier
181
177
  end
178
+
179
+ aliases.first
182
180
  end
183
181
  end
184
182
 
185
- # Sets the current alias.
183
+ # Returns the current name.
186
184
  #
187
- # @param new_alias [String] The new current alias.
188
- def current_alias=(new_alias)
189
- @current_alias = new_alias.ensure_string
185
+ # @param dst [Boolean] If to return the name with DST indication.
186
+ # @param dst_label [String] Label for the DST indication. Defaults to ` (DST)`.
187
+ # @param year [Fixnum] The year to which refer to. Defaults to the current year. *Only required when `dst` is true*.
188
+ # @return [String] The name for the zone.
189
+ def current_name(dst = false, dst_label: " (DST)", year: nil)
190
+ year ||= Date.current.year
191
+ rv = current_alias
192
+ rv += dst_label if dst && uses_dst?(year)
193
+ rv
190
194
  end
191
195
 
192
196
  # Returns the standard offset for this timezone.
193
197
  #
194
198
  # @param rational [Boolean] If to return the offset as a Rational.
195
- # @return [Fixnum|Rational] The offset of this timezone.
196
- def offset(rational = false)
197
- rational ? self.class.rationalize_offset(utc_offset) : utc_offset
198
- end
199
-
200
- # Gets a period for this timezone when the Daylight Saving Time (DST) is active (it takes care of different hemispheres).
201
- #
199
+ # @param dst [Boolean] If to return the offset when the DST is active.
202
200
  # @param year [Fixnum] The year to which refer to. Defaults to the current year.
203
- # @return [TimezonePeriod] A period when the Daylight Saving Time (DST) is active or `nil` if the timezone doesn't use DST for that year.
204
- def dst_period(year = nil)
205
- year ||= ::Date.today.year
206
-
207
- northern_summer = ::DateTime.civil(year, 7, 15).utc # This is a representation of a summer period in the Northern Hemisphere.
208
- southern_summer = ::DateTime.civil(year, 1, 15).utc # This is a representation of a summer period in the Southern Hemisphere.
201
+ # @return [Fixnum|Rational] The offset of this timezone.
202
+ def offset(rational: false, dst: false, year: nil)
203
+ rv =
204
+ if dst
205
+ period = dst_period(year)
206
+ period ? period.utc_total_offset : 0
207
+ else
208
+ utc_offset
209
+ end
209
210
 
210
- period = period_for_utc(northern_summer)
211
- period = period_for_utc(southern_summer) unless period.dst?
212
- period.dst? ? period : nil
211
+ rational ? self.class.rationalize_offset(rv) : rv
213
212
  end
214
213
 
215
214
  # Checks if the timezone uses Daylight Saving Time (DST) for that date or year.
216
215
  #
217
- # @param reference [Object] The date or year to check. Defaults to the current year.
216
+ # @param reference [Date|DateTime] The date or year to check. Defaults to the current year.
218
217
  # @return [Boolean] `true` if the zone uses DST for that date or year, `false` otherwise.
219
218
  def uses_dst?(reference = nil)
220
- if reference.respond_to?(:year) && reference.respond_to?(:utc) # This is a date like object
221
- dst_period(reference.year).present? && period_for_utc(reference.utc).dst?
219
+ if reference.is_a?(Date) || reference.is_a?(DateTime) || reference.is_a?(Time)
220
+ period_for_utc(reference).dst?
222
221
  else
223
- dst_period(reference).present?
222
+ dst_period(reference)
224
223
  end
225
224
  end
226
225
 
227
- # Return the correction applied to the standard offset the timezone when the Daylight Saving Time (DST) is active.
226
+ # Gets a period for this timezone when the Daylight Saving Time (DST) is active (it takes care of different hemispheres).
228
227
  #
229
- # @param rational [Boolean] If to return the offset as a Rational.
230
228
  # @param year [Fixnum] The year to which refer to. Defaults to the current year.
231
- # @return [Fixnum|Rational] The correction for dst.
232
- def dst_correction(rational = false, year = nil)
233
- dst_offset(rational, year, :std_offset)
229
+ # @return [TimezonePeriod] A period when the Daylight Saving Time (DST) is active or `nil` if the timezone doesn't use DST for that year.
230
+ def dst_period(year = nil)
231
+ year ||= ::Date.current.year
232
+
233
+ period = period_for_utc(::DateTime.civil(year, 7, 15, 12).utc) # Summer for the northern hemisphere
234
+ period = period_for_utc(::DateTime.civil(year, 1, 15, 12).utc) unless period.dst? # Summer for the southern hemisphere
235
+ period.dst? ? period : nil
236
+ rescue
237
+ nil
234
238
  end
235
239
 
236
- # Returns the standard offset for this timezone timezone when the Daylight Saving Time (DST) is active.
240
+ # Return the correction applied to the standard offset the timezone when the Daylight Saving Time (DST) is active.
237
241
  #
238
242
  # @param rational [Boolean] If to return the offset as a Rational.
239
243
  # @param year [Fixnum] The year to which refer to. Defaults to the current year.
240
- # @param method [Symbol] The method to use for getting the offset. Default is total offset from UTC.
241
- # @return [Fixnum|Rational] The DST offset for this timezone or `0`, if the timezone doesn't use DST for that year.
242
- def dst_offset(rational = false, year = nil, method = :utc_total_offset)
243
- period = dst_period(year)
244
- rv = period ? period.send(method) : 0
244
+ # @return [Fixnum|Rational] The correction for dst.
245
+ def dst_correction(rational = false, year = nil)
246
+ rv = dst_offset(year, :std_offset)
245
247
  rational ? self.class.rationalize_offset(rv) : rv
246
248
  end
247
249
 
248
- # Returns the name for this zone with Daylight Saving Time (DST) active.
250
+ # Formats this zone as a string.
249
251
  #
250
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
251
- # @param year [Fixnum] The year to which refer to. Defaults to the current year.
252
- # @param name [String] The name to use for this zone. Defaults to the zone name.
253
- # @return [String] The name for the zone with DST or `nil`, if the timezone doesn't use DST for that year.
254
- def dst_name(dst_label = nil, year = nil, name = nil)
255
- uses_dst?(year) ? "#{name || self.name} #{dst_label || "(DST)"}" : nil
256
- end
257
-
258
- # Returns the name for this zone with Daylight Saving Time (DST) active.
252
+ # @param dst [Boolean] If to represent with (DST) active.
253
+ # @param args [Hash] Parameters for the formatting:
259
254
  #
260
- # @param name [String] The name to use for this zone. Defaults to the zone name.
261
- # @param colon [Boolean] If to put the colon in the output string.
262
- # @return [String] The name for this zone.
263
- def to_str(name = nil, colon = true)
264
- "(GMT#{formatted_offset(colon)}) #{name || current_alias}"
265
- end
266
-
267
- # Returns a string representation for this zone with Daylight Saving Time (DST) active.
255
+ # * **label** (`String`): The label to use. Default to the current alias.
256
+ # * **dst_label** (`String`): Label for the DST indication. Defaults to ` (DST)`.
257
+ # * **utc_label** (`String`): Label for the UTC name. Defaults to `GMT`. *Only used when `parameterized` is `false`.
258
+ # * **year** (`Fixnum`): The year to which refer to. Defaults to the current year.
259
+ # * **parameterized** (`Boolean`): If to represent as parameterized.
260
+ # * **with_offset** (`Boolean`): If to include offset into the representation. *Only used when `parameterized` is `true`.
261
+ # * **offset_position** (`Symbol`): Where to put the offset. Valid values are `:begin` or `:end`. *Only used when `parameterized` is `false`.
262
+ # * **colon** (`Boolean`): If include a colon in the offset. *Only used when `parameterized` is `false`.
268
263
  #
269
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
270
- # @param year [Fixnum] The year to which refer to. Defaults to the current year.
271
- # @param name [String] The name to use for this zone. Defaults to the zone name.
272
- # @return [String] The string representation for the zone with DST or `nil`, if the timezone doesn't use DST for that year.
273
- def to_str_with_dst(dst_label = nil, year = nil, name = nil)
274
- uses_dst?(year) ? "(GMT#{self.class.seconds_to_utc_offset(dst_period(year).utc_total_offset)}) #{name || current_alias} #{dst_label || "(DST)"}" : nil
275
- end
264
+ # @return [String] The string representation for this zone.
265
+ def to_str(dst = false, **args)
266
+ # PI: Ignore reek on this.
267
+ label, dst_label, utc_label, year, parameterized, with_offset, colon, offset_position = prepare_to_str_arguments(args)
276
268
 
277
- # Returns a parameterized string representation for this zone.
278
- #
279
- # @param with_offset [Boolean] If to include offset into the representation.
280
- # @param name [String] The name to use for this zone. Defaults to the zone name.
281
- # @return [String] The parameterized string representation for this zone.
282
- def to_str_parameterized(with_offset = true, name = nil)
283
- ::ActiveSupport::TimeZone.parameterize_zone(name || to_str, with_offset)
284
- end
269
+ if parameterized
270
+ self.class.parameterize(to_str(dst, label: label, dst_label: dst_label, utc_label: utc_label, year: year, parameterized: false), with_offset)
271
+ else
272
+ offset_label = self.class.seconds_to_utc_offset(offset(rational: false, dst: dst, year: year), colon)
273
+ dst_label = "" unless dst
285
274
 
286
- # Returns a parameterized string representation for this zone with Daylight Saving Time (DST) active.
287
- #
288
- # @param dst_label [String] Label for the DST indication. Defaults to `(DST)`.
289
- # @param year [Fixnum] The year to which refer to. Defaults to the current year.
290
- # @param name [String] The name to use for this zone. Defaults to the zone name.
291
- # @return [String] The parameterized string representation for this zone with DST or `nil`, if the timezone doesn't use DST for that year.
292
- def to_str_with_dst_parameterized(dst_label = nil, year = nil, name = nil)
293
- rv = to_str_with_dst(dst_label, year, name)
294
- rv ? ::ActiveSupport::TimeZone.parameterize_zone(rv) : nil
275
+ to_str_unparameterized(dst_label, label, offset_label, offset_position, utc_label, with_offset)
276
+ end
295
277
  end
296
278
 
297
279
  private
298
280
 
299
- # Formats a time zone alias.
300
- #
301
- # @param name [String] The zone name.
302
- # @param zone [String] The zone.
303
- # @param reference [String] The main name for the zone.
304
- # @return [String|nil] The formatted alias.
281
+ # :nodoc
305
282
  def format_alias(name, zone, reference)
306
283
  if zone.gsub("_", " ") == reference
307
284
  ["International Date Line West", "UTC"].include?(name) || name.include?("(US & Canada)") ? name : reference.gsub(/\/.*/, "/#{name}")
@@ -309,5 +286,32 @@ module Lazier
309
286
  nil
310
287
  end
311
288
  end
289
+
290
+ # :nodoc:
291
+ def dst_offset(year, method)
292
+ period = dst_period(year)
293
+ period ? period.send(method) : 0
294
+ end
295
+
296
+ # :nodoc:
297
+ def prepare_to_str_arguments(args)
298
+ args = args.reverse_merge(
299
+ label: current_alias, dst_label: " (DST)", utc_label: "GMT", year: nil, parameterized: false,
300
+ with_offset: true, colon: true, offset_position: :begin
301
+ ).symbolize_keys
302
+
303
+ [:label, :dst_label, :utc_label, :year, :parameterized, :with_offset, :colon, :offset_position].map { |e| args[e] }
304
+ end
305
+
306
+ # :nodoc:
307
+ def to_str_unparameterized(dst_label, label, offset_label, offset_position, utc_label, with_offset)
308
+ if !with_offset
309
+ format("%s%s", label, dst_label)
310
+ elsif offset_position != :end
311
+ format("(%s%s) %s%s", utc_label, offset_label, label, dst_label)
312
+ else
313
+ format("%s%s (%s%s)", label, dst_label, utc_label, offset_label)
314
+ end
315
+ end
312
316
  end
313
317
  end