Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 481 lines (429 sloc) 24.974 kb
31319b4 Joshua Peek NumberHelper depends on big decimal extensions
josh authored
1 require 'active_support/core_ext/big_decimal/conversions'
b2d6fda Jeremy Kemper Fix tests on 1.9
jeremy authored
2 require 'active_support/core_ext/float/rounding'
76f024a Xavier Noria adds missing requires for Object#blank? and Object#present?
fxn authored
3 require 'active_support/core_ext/object/blank'
5f60735 Santiago Pastorino Add missing require
spastorino authored
4 require 'active_support/core_ext/string/output_safety'
b2d6fda Jeremy Kemper Fix tests on 1.9
jeremy authored
5
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
6 module ActionView
1a0dc26 Rizwan Reza Action View is now titled.
rizwanreza authored
7 # = Action View Number Helpers
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
8 module Helpers #:nodoc:
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
9
9ffb632 Enhance documentation coverage for fragment caching. Closes #7315 [bscof...
Marcel Molina authored
10 # Provides methods for converting numbers into formatted strings.
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
11 # Methods are provided for phone numbers, currency, percentage,
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
12 # precision, positional notation, file size and pretty printing.
13 #
14 # Most methods expect a +number+ argument, and will return it
15 # unchanged if can't be converted into a valid number.
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
16 module NumberHelper
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
17
c7e6777 Santiago Pastorino Added default currency values to NumberHelper and pass them to I18n.tran...
spastorino authored
18 DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :unit => "$", :separator => ".", :delimiter => ",",
19 :precision => 2, :significant => false, :strip_insignificant_zeros => false }
20
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
21 # Raised when argument +number+ param given to the helpers is invalid and
22 # the option :raise is set to +true+.
23 class InvalidNumberError < StandardError
24 attr_accessor :number
25 def initialize(number)
26 @number = number
27 end
28 end
29
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
30 # Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
31 # in the +options+ hash.
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
32 #
33 # ==== Options
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
34 # * <tt>:area_code</tt> - Adds parentheses around the area code.
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
35 # * <tt>:delimiter</tt> - Specifies the delimiter to use (defaults to "-").
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
36 # * <tt>:extension</tt> - Specifies an extension to add to the end of the
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
37 # generated number.
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
38 # * <tt>:country_code</tt> - Sets the country code for the phone number.
39 #
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
40 # ==== Examples
1ab2ff5 Ryan Heath Fixed number_to_phone to work with 7 digit numbers [#2176 state:resolved...
rpheath authored
41 # number_to_phone(5551234) # => 555-1234
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
42 # number_to_phone(1235551234) # => 123-555-1234
43 # number_to_phone(1235551234, :area_code => true) # => (123) 555-1234
44 # number_to_phone(1235551234, :delimiter => " ") # => 123 555 1234
45 # number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
46 # number_to_phone(1235551234, :country_code => 1) # => +1-123-555-1234
47 #
2af36bb David Heinemeier Hansson Fix typos (closes #10378)
dhh authored
48 # number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
49 # => +1.123.555.1234 x 1343
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
50 def number_to_phone(number, options = {})
98d3c41 Aaron Patterson implicit return of nil
tenderlove authored
51 return unless number
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
52
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
53 begin
54 Float(number)
55 rescue ArgumentError, TypeError
0d5d70f Santiago Pastorino parse number only if options[:raise] is provided
spastorino authored
56 raise InvalidNumberError, number
57 end if options[:raise]
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
58
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
59 number = number.to_s.strip
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
60 options = options.symbolize_keys
dfb3ff6 Santiago Pastorino This or login doesn't make sense
spastorino authored
61 area_code = options[:area_code]
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
62 delimiter = options[:delimiter] || "-"
1a0f72d Santiago Pastorino Why strip only the extension, this can be done by the user
spastorino authored
63 extension = options[:extension]
dfb3ff6 Santiago Pastorino This or login doesn't make sense
spastorino authored
64 country_code = options[:country_code]
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
65
31ac1db Santiago Pastorino Tidy up a bit this code
spastorino authored
66 if area_code
9c219bf Aaron Patterson use regex escape sequences to shorten stuff up
tenderlove authored
67 number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
68 else
9c219bf Aaron Patterson use regex escape sequences to shorten stuff up
tenderlove authored
69 number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
31ac1db Santiago Pastorino Tidy up a bit this code
spastorino authored
70 number.slice!(0, 1) if number.starts_with?('-')
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
71 end
31ac1db Santiago Pastorino Tidy up a bit this code
spastorino authored
72
081e15f Aaron Patterson join strings rather than resizing buffer
tenderlove authored
73 str = []
31ac1db Santiago Pastorino Tidy up a bit this code
spastorino authored
74 str << "+#{country_code}#{delimiter}" unless country_code.blank?
75 str << number
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
76 str << " x #{extension}" unless extension.blank?
081e15f Aaron Patterson join strings rather than resizing buffer
tenderlove authored
77 ERB::Util.html_escape(str.join)
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
78 end
79
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
80 # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
81 # in the +options+ hash.
82 #
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
83 # ==== Options
59e89fa Slobodan Kovacevic Added :locale option explanation for number_to_currency
basti authored
84 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
85 # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
86 # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
87 # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
88 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
89 # * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
3c0fd44 David Heinemeier Hansson Added :format option to NumberHelper#number_to_currency to enable better...
dhh authored
90 #
91 # %u The currency unit
92 # %n The number
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
93 #
94 # ==== Examples
95 # number_to_currency(1234567890.50) # => $1,234,567,890.50
96 # number_to_currency(1234567890.506) # => $1,234,567,890.51
97 # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
98 # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
99 #
2823a56 Jeremy Kemper Deprecation: remove deprecated human_size helper alias. Use number_to_hu...
jeremy authored
100 # number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
101 # # => &pound;1234567890,50
3c0fd44 David Heinemeier Hansson Added :format option to NumberHelper#number_to_currency to enable better...
dhh authored
102 # number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
103 # # => 1234567890,50 &pound;
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
104 def number_to_currency(number, options = {})
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
105 return nil if number.nil?
106
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
107 options.symbolize_keys!
108
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
109 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
110 currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
111
c7e6777 Santiago Pastorino Added default currency values to NumberHelper and pass them to I18n.tran...
spastorino authored
112 defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
113 options = defaults.merge!(options)
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
114
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
115 unit = options.delete(:unit)
116 format = options.delete(:format)
117
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
118 begin
119 value = number_with_precision(number, options.merge(:raise => true))
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
120 format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
121 rescue InvalidNumberError => e
122 if options[:raise]
123 raise
124 else
125 formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit)
126 e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
127 end
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
128 end
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
129
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
130 end
131
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
132 # Formats a +number+ as a percentage string (e.g., 65%). You can customize the
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
133 # format in the +options+ hash.
134 #
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
135 # ==== Options
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
136 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
137 # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
138 # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
139 # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
140 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
141 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +false+)
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
142 #
143 # ==== Examples
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
144 # number_to_percentage(100) # => 100.000%
145 # number_to_percentage(100, :precision => 0) # => 100%
146 # number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
147 # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
148 # number_to_percentage(1000, :locale => :fr) # => 1 000,000%
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
149 def number_to_percentage(number, options = {})
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
150 return nil if number.nil?
151
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
152 options.symbolize_keys!
153
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
154 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
155 percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
dc66469 Clemens Kofler Fixed i18n bulk translate issues in NumberHelper
clemens authored
156 defaults = defaults.merge(percentage)
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
157
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
158 options = options.reverse_merge(defaults)
2823a56 Jeremy Kemper Deprecation: remove deprecated human_size helper alias. Use number_to_hu...
jeremy authored
159
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
160 begin
161 "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
162 rescue InvalidNumberError => e
163 if options[:raise]
164 raise
165 else
166 e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
167 end
168 end
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
169 end
170
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
171 # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
172 # customize the format in the +options+ hash.
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
173 #
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
174 # ==== Options
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
175 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
176 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
177 # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
178 #
179 # ==== Examples
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
180 # number_with_delimiter(12345678) # => 12,345,678
181 # number_with_delimiter(12345678.05) # => 12,345,678.05
182 # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
18eb80c Pratik Merge docrails
lifo authored
183 # number_with_delimiter(12345678, :separator => ",") # => 12,345,678
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
184 # number_with_delimiter(12345678.05, :locale => :fr) # => 12 345 678,05
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
185 # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
186 # # => 98 765 432,98
da84527 Łukasz Strzałkowski Removed deprecated APIs in text and number helpers [#5156 state:resolved...
strzalek authored
187 def number_with_delimiter(number, options = {})
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
188 options.symbolize_keys!
189
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
190 begin
191 Float(number)
192 rescue ArgumentError, TypeError
193 if options[:raise]
194 raise InvalidNumberError, number
195 else
196 return number
197 end
198 end
199
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
200 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
201 options = options.reverse_merge(defaults)
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
202
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
203 parts = number.to_s.split('.')
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
204 parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
205 parts.join(options[:separator]).html_safe
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
206
4bdb25d David Heinemeier Hansson Update to the helper to abstract delimeting a number #1015
dhh authored
207 end
2823a56 Jeremy Kemper Deprecation: remove deprecated human_size helper alias. Use number_to_hu...
jeremy authored
208
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
209 # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision
210 # of 2 if +:significant+ is +false+, and 5 if +:significant+ is +true+).
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
211 # You can customize the format in the +options+ hash.
212 #
213 # ==== Options
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
214 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
215 # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
216 # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
217 # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
218 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
219 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +false+)
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
220 #
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
221 # ==== Examples
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
222 # number_with_precision(111.2345) # => 111.235
223 # number_with_precision(111.2345, :precision => 2) # => 111.23
224 # number_with_precision(13, :precision => 5) # => 13.00000
225 # number_with_precision(389.32314, :precision => 0) # => 389
226 # number_with_precision(111.2345, :significant => true) # => 111
227 # number_with_precision(111.2345, :precision => 1, :significant => true) # => 100
228 # number_with_precision(13, :precision => 5, :significant => true) # => 13.000
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
229 # number_with_precision(111.234, :locale => :fr) # => 111,234
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
230 # number_with_precision(13, :precision => 5, :significant => true, strip_insignificant_zeros => true)
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
231 # # => 13
232 # number_with_precision(389.32314, :precision => 4, :significant => true) # => 389.3
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
233 # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
234 # # => 1.111,23
da84527 Łukasz Strzałkowski Removed deprecated APIs in text and number helpers [#5156 state:resolved...
strzalek authored
235 def number_with_precision(number, options = {})
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
236 options.symbolize_keys!
237
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
238 number = begin
239 Float(number)
240 rescue ArgumentError, TypeError
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
241 if options[:raise]
242 raise InvalidNumberError, number
243 else
244 return number
245 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
246 end
247
248 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
249 precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
dc66469 Clemens Kofler Fixed i18n bulk translate issues in NumberHelper
clemens authored
250 defaults = defaults.merge(precision_defaults)
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
251
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
252 options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
253 precision = options.delete :precision
254 significant = options.delete :significant
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
255 strip_insignificant_zeros = options.delete :strip_insignificant_zeros
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
256
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
257 if significant and precision > 0
81e6933 Bernardo de Pádua Fix error in number_with_precision with :significant option and zero val...
bernardo authored
258 if number == 0
259 digits, rounded_number = 1, 0
260 else
e20012b Santiago Pastorino Make number_to_human and number_with_precision work with negatives
spastorino authored
261 digits = (Math.log10(number.abs) + 1).floor
81e6933 Bernardo de Pádua Fix error in number_with_precision with :significant option and zero val...
bernardo authored
262 rounded_number = BigDecimal.new((number / 10 ** (digits - precision)).to_s).round.to_f * 10 ** (digits - precision)
263 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
264 precision = precision - digits
265 precision = precision > 0 ? precision : 0 #don't let it be negative
266 else
267 rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
268 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
269 formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options)
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
270 if strip_insignificant_zeros
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
271 escaped_separator = Regexp.escape(options[:separator])
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
272 formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe
8da026c Xavier Shay Remove some of the blank rescues from number helper. This makes the code...
xaviershay authored
273 else
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
274 formatted_number
dc66469 Clemens Kofler Fixed i18n bulk translate issues in NumberHelper
clemens authored
275 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
276
1c71a5d David Heinemeier Hansson Upgraded NumberHelper with number_to_phone support international formats...
dhh authored
277 end
2823a56 Jeremy Kemper Deprecation: remove deprecated human_size helper alias. Use number_to_hu...
jeremy authored
278
17db28f Yaroslav Markin Improve i18n support for number_to_human_size helper:
yaroslav authored
279 STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
280
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
281 # Formats the bytes in +number+ into a more understandable representation
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
282 # (e.g., giving it 1500 yields 1.5 KB). This method is useful for
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
283 # reporting file sizes to users. You can customize the
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
284 # format in the +options+ hash.
285 #
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
286 # See <tt>number_to_human</tt> if you want to pretty-print a generic number.
287 #
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
288 # ==== Options
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
289 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
290 # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
291 # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
292 # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
293 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
294 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
b00e6a9 David Heinemeier Hansson Massive documentation update for all helpers (closes #8223, #8177, #8175...
dhh authored
295 # ==== Examples
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
296 # number_to_human_size(123) # => 123 Bytes
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
297 # number_to_human_size(1234) # => 1.21 KB
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
298 # number_to_human_size(12345) # => 12.1 KB
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
299 # number_to_human_size(1234567) # => 1.18 MB
300 # number_to_human_size(1234567890) # => 1.15 GB
301 # number_to_human_size(1234567890123) # => 1.12 TB
302 # number_to_human_size(1234567, :precision => 2) # => 1.2 MB
303 # number_to_human_size(483989, :precision => 2) # => 470 KB
304 # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,2 MB
0f43de6 Clemens Kofler Refactored NumberHelper API to accept arguments as an options hash [#666...
clemens authored
305 #
ccf9577 Ev Dolzhenko Fix a bunch of minor spelling mistakes
dolzenko authored
306 # Non-significant zeros after the fractional separator are stripped out by default (set
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
307 # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
308 # number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB"
309 # number_to_human_size(524288000, :precision=>5) # => "500 MB"
da84527 Łukasz Strzałkowski Removed deprecated APIs in text and number helpers [#5156 state:resolved...
strzalek authored
310 def number_to_human_size(number, options = {})
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
311 options.symbolize_keys!
312
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
313 number = begin
314 Float(number)
315 rescue ArgumentError, TypeError
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
316 if options[:raise]
317 raise InvalidNumberError, number
318 else
319 return number
320 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
321 end
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
322
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
323 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
324 human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
325 defaults = defaults.merge(human)
b451de0 Santiago Pastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
326
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
327 options = options.reverse_merge(defaults)
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
328 #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
329 options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
330
17db28f Yaroslav Markin Improve i18n support for number_to_human_size helper:
yaroslav authored
331 storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
fea7771 Clemens Kofler Updated NumberHelper: Full i18n support (except number_to_phone), consol...
clemens authored
332
17db28f Yaroslav Markin Improve i18n support for number_to_human_size helper:
yaroslav authored
333 if number.to_i < 1024
334 unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
335 storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe
17db28f Yaroslav Markin Improve i18n support for number_to_human_size helper:
yaroslav authored
336 else
337 max_exp = STORAGE_UNITS.size - 1
338 exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
339 exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
340 number /= 1024 ** exponent
341
342 unit_key = STORAGE_UNITS[exponent]
343 unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
344
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
345 formatted_number = number_with_precision(number, options)
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
346 storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe
dc66469 Clemens Kofler Fixed i18n bulk translate issues in NumberHelper
clemens authored
347 end
7140f65 David Heinemeier Hansson Moved TextHelper#human_size to NumberHelper#number_to_human_size, but ke...
dhh authored
348 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
349
350 DECIMAL_UNITS = {0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
351 -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}.freeze
352
353 # Pretty prints (formats and approximates) a number in a way it is more readable by humans
354 # (eg.: 1200000000 becomes "1.2 Billion"). This is useful for numbers that
355 # can get very large (and too hard to read).
356 #
357 # See <tt>number_to_human_size</tt> if you want to print a file size.
358 #
359 # You can also define you own unit-quantifier names if you want to use other decimal units
360 # (eg.: 1500 becomes "1.5 kilometers", 0.150 becomes "150 mililiters", etc). You may define
361 # a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).
362 #
363 # ==== Options
5a74557 Slobodan Kovacevic Updated all number helpers with :locale option.
basti authored
364 # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
365 # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
366 # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
367 # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
368 # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
369 # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
370 # * <tt>:units</tt> - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:
371 # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>, <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>, <tt>:billion</tt>, <tt>:trillion</tt>, <tt>:quadrillion</tt>
372 # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>, <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>, <tt>:pico</tt>, <tt>:femto</tt>
373 # * <tt>:format</tt> - Sets the format of the output string (defaults to "%n %u"). The field types are:
374 #
375 # %u The quantifier (ex.: 'thousand')
376 # %n The number
377 #
378 # ==== Examples
379 # number_to_human(123) # => "123"
380 # number_to_human(1234) # => "1.23 Thousand"
381 # number_to_human(12345) # => "12.3 Thousand"
382 # number_to_human(1234567) # => "1.23 Million"
383 # number_to_human(1234567890) # => "1.23 Billion"
384 # number_to_human(1234567890123) # => "1.23 Trillion"
385 # number_to_human(1234567890123456) # => "1.23 Quadrillion"
386 # number_to_human(1234567890123456789) # => "1230 Quadrillion"
387 # number_to_human(489939, :precision => 2) # => "490 Thousand"
388 # number_to_human(489939, :precision => 4) # => "489.9 Thousand"
389 # number_to_human(1234567, :precision => 4,
390 # :significant => false) # => "1.2346 Million"
391 # number_to_human(1234567, :precision => 1,
392 # :separator => ',',
393 # :significant => false) # => "1,2 Million"
394 #
395 # Unsignificant zeros after the decimal separator are stripped out by default (set
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
396 # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
397 # number_to_human(12345012345, :significant_digits => 6) # => "12.345 Billion"
398 # number_to_human(500000000, :precision=>5) # => "500 Million"
399 #
400 # ==== Custom Unit Quantifiers
401 #
402 # You can also use your own custom unit quantifiers:
403 # number_to_human(500000, :units => {:unit => "ml", :thousand => "lt"}) # => "500 lt"
404 #
405 # If in your I18n locale you have:
406 # distance:
407 # centi:
408 # one: "centimeter"
409 # other: "centimeters"
410 # unit:
411 # one: "meter"
412 # other: "meters"
413 # thousand:
414 # one: "kilometer"
415 # other: "kilometers"
416 # billion: "gazilion-distance"
417 #
418 # Then you could do:
419 #
420 # number_to_human(543934, :units => :distance) # => "544 kilometers"
421 # number_to_human(54393498, :units => :distance) # => "54400 kilometers"
422 # number_to_human(54393498000, :units => :distance) # => "54.4 gazilion-distance"
423 # number_to_human(343, :units => :distance, :precision => 1) # => "300 meters"
424 # number_to_human(1, :units => :distance) # => "1 meter"
425 # number_to_human(0.34, :units => :distance) # => "34 centimeters"
426 #
427 def number_to_human(number, options = {})
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
428 options.symbolize_keys!
429
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
430 number = begin
431 Float(number)
432 rescue ArgumentError, TypeError
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
433 if options[:raise]
434 raise InvalidNumberError, number
435 else
436 return number
437 end
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
438 end
439
440 defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
441 human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
442 defaults = defaults.merge(human)
443
444 options = options.reverse_merge(defaults)
c53f77f José Valim Rename unsignificant to insignificant.
josevalim authored
445 #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
446 options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
447
448 units = options.delete :units
449 unit_exponents = case units
450 when Hash
451 units
452 when String, Symbol
453 I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
454 when nil
455 I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true)
456 else
457 raise ArgumentError, ":units must be a Hash or String translation scope."
458 end.keys.map{|e_name| DECIMAL_UNITS.invert[e_name] }.sort_by{|e| -e}
459
e20012b Santiago Pastorino Make number_to_human and number_with_precision work with negatives
spastorino authored
460 number_exponent = number != 0 ? Math.log10(number.abs).floor : 0
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
461 display_exponent = unit_exponents.find{|e| number_exponent >= e }
462 number /= 10 ** display_exponent
463
464 unit = case units
465 when Hash
466 units[DECIMAL_UNITS[display_exponent]]
467 when String, Symbol
468 I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
469 else
470 I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
471 end
472
473 decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u")
474 formatted_number = number_with_precision(number, options)
a4090bc Bernardo de Pádua NumberHelper methods should now return html_safe strings (when the input...
bernardo authored
475 decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
75904c5 Bernardo de Pádua Adds number_to_human and several improvements in NumberHelper. [#4239 st...
bernardo authored
476 end
477
aa09c77 David Heinemeier Hansson Added NumberHelper for common string representations like phone number, ...
dhh authored
478 end
479 end
5cd815a David Heinemeier Hansson Fixed spelling of delimiter #1058
dhh authored
480 end
Something went wrong with that request. Please try again.