Class Index [+]

Quicksearch

ActionView::Helpers::NumberHelper

Provides methods for converting numbers into formatted strings. Methods are provided for phone numbers, currency, percentage, precision, positional notation, file size and pretty printing.

Most methods expect a number argument, and will return it unchanged if can’t be converted into a valid number.

Constants

DEFAULT_CURRENCY_VALUES
STORAGE_UNITS
DECIMAL_UNITS

Public Instance Methods

number_to_currency(number, options = {}) click to toggle source

Formats a number into a currency string (e.g., $13.65). You can customize the format in the options hash.

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :precision - Sets the level of precision (defaults to 2).

  • :unit - Sets the denomination of the currency (defaults to “$”).

  • :separator - Sets the separator between the units (defaults to “.”).

  • :delimiter - Sets the thousands delimiter (defaults to “,”).

  • :format - Sets the format for non-negative numbers (defaults to “%u%n”). Fields are %u for the currency, and %n for the number.

  • :negative_format - Sets the format for negative numbers (defaults to prepending an hyphen to the formatted number given by :format). Accepts the same fields than :format, except %n is here the absolute value of the number.

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_to_currency(1234567890.50)                    # => $1,234,567,890.50
 number_to_currency(1234567890.506)                   # => $1,234,567,890.51
 number_to_currency(1234567890.506, :precision => 3)  # => $1,234,567,890.506
 number_to_currency(1234567890.506, :locale => :fr)   # => 1 234 567 890,51 €
 number_to_currency("123a456")                        # => $123a456

 number_to_currency("123a456", :raise => true)        # => InvalidNumberError

 number_to_currency(-1234567890.50, :negative_format => "(%u%n)")
 # => ($1,234,567,890.50)
 number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
 # => £1234567890,50
 number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
 # => 1234567890,50 £
     # File lib/action_view/helpers/number_helper.rb, line 134
134:       def number_to_currency(number, options = {})
135:         return unless number
136: 
137:         options.symbolize_keys!
138: 
139:         defaults  = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
140:         currency  = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
141:         currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
142: 
143:         defaults  = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
144:         defaults[:negative_format] = "-" + options[:format] if options[:format]
145:         options   = defaults.merge!(options)
146: 
147:         unit      = options.delete(:unit)
148:         format    = options.delete(:format)
149: 
150:         if number.to_f < 0
151:           format = options.delete(:negative_format)
152:           number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
153:         end
154: 
155:         begin
156:           value = number_with_precision(number, options.merge(:raise => true))
157:           format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
158:         rescue InvalidNumberError => e
159:           if options[:raise]
160:             raise
161:           else
162:             formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit)
163:             e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
164:           end
165:         end
166: 
167:       end
number_to_human(number, options = {}) click to toggle source

Pretty prints (formats and approximates) a number in a way it is more readable by humans (eg.: 1200000000 becomes “1.2 Billion”). This is useful for numbers that can get very large (and too hard to read).

See number_to_human_size if you want to print a file size.

You can also define you own unit-quantifier names if you want to use other decimal units (eg.: 1500 becomes “1.5 kilometers”, 0.150 becomes “150 milliliters”, etc). You may define a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :precision - Sets the precision of the number (defaults to 3).

  • :significant - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to true)

  • :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

  • :delimiter - Sets the thousands delimiter (defaults to “”).

  • :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

  • :units - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:

    • integers: :unit, :ten, *:hundred, :thousand, :million, *:billion, :trillion, *:quadrillion

    • fractionals: :deci, :centi, *:mili, :micro, :nano, *:pico, :femto

  • :format - Sets the format of the output string (defaults to “%n %u”). The field types are:

    • %u - The quantifier (ex.: ‘thousand’)

    • %n - The number

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_to_human(123)                                          # => "123"
 number_to_human(1234)                                         # => "1.23 Thousand"
 number_to_human(12345)                                        # => "12.3 Thousand"
 number_to_human(1234567)                                      # => "1.23 Million"
 number_to_human(1234567890)                                   # => "1.23 Billion"
 number_to_human(1234567890123)                                # => "1.23 Trillion"
 number_to_human(1234567890123456)                             # => "1.23 Quadrillion"
 number_to_human(1234567890123456789)                          # => "1230 Quadrillion"
 number_to_human(489939, :precision => 2)                      # => "490 Thousand"
 number_to_human(489939, :precision => 4)                      # => "489.9 Thousand"
 number_to_human(1234567, :precision => 4,
                          :significant => false)               # => "1.2346 Million"
 number_to_human(1234567, :precision => 1,
                          :separator => ',',
                          :significant => false)               # => "1,2 Million"

Non-significant zeros after the decimal separator are stripped out by default (set :strip_insignificant_zeros to false to change that):

 number_to_human(12345012345, :significant_digits => 6)       # => "12.345 Billion"
 number_to_human(500000000, :precision => 5)                  # => "500 Million"

Custom Unit Quantifiers

You can also use your own custom unit quantifiers:

 number_to_human(500000, :units => {:unit => "ml", :thousand => "lt"})  # => "500 lt"

If in your I18n locale you have:

  distance:
    centi:
      one: "centimeter"
      other: "centimeters"
    unit:
      one: "meter"
      other: "meters"
    thousand:
      one: "kilometer"
      other: "kilometers"
    billion: "gazillion-distance"

Then you could do:

 number_to_human(543934, :units => :distance)                              # => "544 kilometers"
 number_to_human(54393498, :units => :distance)                            # => "54400 kilometers"
 number_to_human(54393498000, :units => :distance)                         # => "54.4 gazillion-distance"
 number_to_human(343, :units => :distance, :precision => 1)                # => "300 meters"
 number_to_human(1, :units => :distance)                                   # => "1 meter"
 number_to_human(0.34, :units => :distance)                                # => "34 centimeters"
     # File lib/action_view/helpers/number_helper.rb, line 553
553:       def number_to_human(number, options = {})
554:         options.symbolize_keys!
555: 
556:         number = begin
557:           Float(number)
558:         rescue ArgumentError, TypeError
559:           if options[:raise]
560:             raise InvalidNumberError, number
561:           else
562:             return number
563:           end
564:         end
565: 
566:         defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
567:         human    = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
568:         defaults = defaults.merge(human)
569: 
570:         options = options.reverse_merge(defaults)
571:         #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
572:         options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
573: 
574:         inverted_du = DECIMAL_UNITS.invert
575: 
576:         units = options.delete :units
577:         unit_exponents = case units
578:         when Hash
579:           units
580:         when String, Symbol
581:           I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
582:         when nil
583:           I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true)
584:         else
585:           raise ArgumentError, ":units must be a Hash or String translation scope."
586:         end.keys.map{|e_name| inverted_du[e_name] }.sort_by{|e| -e}
587: 
588:         number_exponent = number != 0 ? Math.log10(number.abs).floor : 0
589:         display_exponent = unit_exponents.find{ |e| number_exponent >= e } || 0
590:         number  /= 10 ** display_exponent
591: 
592:         unit = case units
593:         when Hash
594:           units[DECIMAL_UNITS[display_exponent]]
595:         when String, Symbol
596:           I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
597:         else
598:           I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
599:         end
600: 
601:         decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u")
602:         formatted_number = number_with_precision(number, options)
603:         decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
604:       end
number_to_human_size(number, options = {}) click to toggle source

Formats the bytes in number into a more understandable representation (e.g., giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to users. You can customize the format in the options hash.

See number_to_human if you want to pretty-print a generic number.

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :precision - Sets the precision of the number (defaults to 3).

  • :significant - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to true)

  • :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

  • :delimiter - Sets the thousands delimiter (defaults to “”).

  • :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to true)

  • :prefix - If :si formats the number using the SI prefix (defaults to :binary)

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_to_human_size(123)                                          # => 123 Bytes
 number_to_human_size(1234)                                         # => 1.21 KB
 number_to_human_size(12345)                                        # => 12.1 KB
 number_to_human_size(1234567)                                      # => 1.18 MB
 number_to_human_size(1234567890)                                   # => 1.15 GB
 number_to_human_size(1234567890123)                                # => 1.12 TB
 number_to_human_size(1234567, :precision => 2)                     # => 1.2 MB
 number_to_human_size(483989, :precision => 2)                      # => 470 KB
 number_to_human_size(1234567, :precision => 2, :separator => ',')  # => 1,2 MB

Non-significant zeros after the fractional separator are stripped out by default (set :strip_insignificant_zeros to false to change that):

 number_to_human_size(1234567890123, :precision => 5)        # => "1.1229 TB"
 number_to_human_size(524288000, :precision => 5)            # => "500 MB"
     # File lib/action_view/helpers/number_helper.rb, line 410
410:       def number_to_human_size(number, options = {})
411:         options.symbolize_keys!
412: 
413:         number = begin
414:           Float(number)
415:         rescue ArgumentError, TypeError
416:           if options[:raise]
417:             raise InvalidNumberError, number
418:           else
419:             return number
420:           end
421:         end
422: 
423:         defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
424:         human    = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
425:         defaults = defaults.merge(human)
426: 
427:         options = options.reverse_merge(defaults)
428:         #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
429:         options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
430: 
431:         storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
432: 
433:         base = options[:prefix] == :si ? 1000 : 1024
434: 
435:         if number.to_i < base
436:           unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
437:           storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe
438:         else
439:           max_exp  = STORAGE_UNITS.size - 1
440:           exponent = (Math.log(number) / Math.log(base)).to_i # Convert to base
441:           exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
442:           number  /= base ** exponent
443: 
444:           unit_key = STORAGE_UNITS[exponent]
445:           unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
446: 
447:           formatted_number = number_with_precision(number, options)
448:           storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe
449:         end
450:       end
number_to_percentage(number, options = {}) click to toggle source

Formats a number as a percentage string (e.g., 65%). You can customize the format in the options hash.

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :precision - Sets the precision of the number (defaults to 3).

  • :significant - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to false).

  • :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

  • :delimiter - Sets the thousands delimiter (defaults to “”).

  • :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_to_percentage(100)                                        # => 100.000%
 number_to_percentage("98")                                       # => 98.000%
 number_to_percentage(100, :precision => 0)                       # => 100%
 number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
 number_to_percentage(302.24398923423, :precision => 5)           # => 302.24399%
 number_to_percentage(1000, :locale => :fr)                       # => 1 000,000%
 number_to_percentage("98a")                                      # => 98a%

 number_to_percentage("98a", :raise => true)                      # => InvalidNumberError
     # File lib/action_view/helpers/number_helper.rb, line 202
202:       def number_to_percentage(number, options = {})
203:         return unless number
204: 
205:         options.symbolize_keys!
206: 
207:         defaults   = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
208:         percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
209:         defaults  = defaults.merge(percentage)
210: 
211:         options = options.reverse_merge(defaults)
212: 
213:         begin
214:           "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
215:         rescue InvalidNumberError => e
216:           if options[:raise]
217:             raise
218:           else
219:             e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
220:           end
221:         end
222:       end
number_to_phone(number, options = {}) click to toggle source

Formats a number into a US phone number (e.g., (555) 123-9876). You can customize the format in the options hash.

Options

  • :area_code - Adds parentheses around the area code.

  • :delimiter - Specifies the delimiter to use (defaults to “-”).

  • :extension - Specifies an extension to add to the end of the generated number.

  • :country_code - Sets the country code for the phone number.

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_to_phone(5551234)                                           # => 555-1234
 number_to_phone("5551234")                                         # => 555-1234
 number_to_phone(1235551234)                                        # => 123-555-1234
 number_to_phone(1235551234, :area_code => true)                    # => (123) 555-1234
 number_to_phone(1235551234, :delimiter => " ")                     # => 123 555 1234
 number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
 number_to_phone(1235551234, :country_code => 1)                    # => +1-123-555-1234
 number_to_phone("123a456")                                         # => 123a456

 number_to_phone("1234a567", :raise => true)                        # => InvalidNumberError

 number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
 # => +1.123.555.1234 x 1343
    # File lib/action_view/helpers/number_helper.rb, line 62
62:       def number_to_phone(number, options = {})
63:         return unless number
64: 
65:         begin
66:           Float(number)
67:         rescue ArgumentError, TypeError
68:           raise InvalidNumberError, number
69:         end if options[:raise]
70: 
71:         number       = number.to_s.strip
72:         options      = options.symbolize_keys
73:         area_code    = options[:area_code]
74:         delimiter    = options[:delimiter] || "-"
75:         extension    = options[:extension]
76:         country_code = options[:country_code]
77: 
78:         if area_code
79:           number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
80:         else
81:           number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
82:           number.slice!(0, 1) if number.starts_with?(delimiter) && !delimiter.blank?
83:         end
84: 
85:         str = []
86:         str << "+#{country_code}#{delimiter}" unless country_code.blank?
87:         str << number
88:         str << " x #{extension}" unless extension.blank?
89:         ERB::Util.html_escape(str.join)
90:       end
number_with_delimiter(number, options = {}) click to toggle source

Formats a number with grouped thousands using delimiter (e.g., 12,324). You can customize the format in the options hash.

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :delimiter - Sets the thousands delimiter (defaults to “,”).

  • :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_with_delimiter(12345678)                        # => 12,345,678
 number_with_delimiter("123456")                        # => 123,456
 number_with_delimiter(12345678.05)                     # => 12,345,678.05
 number_with_delimiter(12345678, :delimiter => ".")     # => 12.345.678
 number_with_delimiter(12345678, :delimiter => ",")     # => 12,345,678
 number_with_delimiter(12345678.05, :separator => " ")  # => 12,345,678 05
 number_with_delimiter(12345678.05, :locale => :fr)     # => 12 345 678,05
 number_with_delimiter("112a")                          # => 112a
 number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
 # => 98 765 432,98

 number_with_delimiter("112a", :raise => true)          # => raise InvalidNumberError
     # File lib/action_view/helpers/number_helper.rb, line 253
253:       def number_with_delimiter(number, options = {})
254:         options.symbolize_keys!
255: 
256:         begin
257:           Float(number)
258:         rescue ArgumentError, TypeError
259:           if options[:raise]
260:             raise InvalidNumberError, number
261:           else
262:             return number
263:           end
264:         end
265: 
266:         defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
267:         options = options.reverse_merge(defaults)
268: 
269:         parts = number.to_s.to_str.split('.')
270:         parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
271:         parts.join(options[:separator]).html_safe
272: 
273:       end
number_with_precision(number, options = {}) click to toggle source

Formats a number with the specified level of :precision (e.g., 112.32 has a precision of 2 if :significant is false, and 5 if :significant is true). You can customize the format in the options hash.

Options

  • :locale - Sets the locale to be used for formatting (defaults to current locale).

  • :precision - Sets the precision of the number (defaults to 3).

  • :significant - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to false).

  • :separator - Sets the separator between the fractional and integer digits (defaults to “.”).

  • :delimiter - Sets the thousands delimiter (defaults to “”).

  • :strip_insignificant_zeros - If true removes insignificant zeros after the decimal separator (defaults to false).

  • :raise - If true, raises InvalidNumberError when the argument is invalid.

Examples

 number_with_precision(111.2345)                                            # => 111.235
 number_with_precision(111.2345, :precision => 2)                           # => 111.23
 number_with_precision(13, :precision => 5)                                 # => 13.00000
 number_with_precision(389.32314, :precision => 0)                          # => 389
 number_with_precision(111.2345, :significant => true)                      # => 111
 number_with_precision(111.2345, :precision => 1, :significant => true)     # => 100
 number_with_precision(13, :precision => 5, :significant => true)           # => 13.000
 number_with_precision(111.234, :locale => :fr)                             # => 111,234

 number_with_precision(13, :precision => 5, :significant => true, :strip_insignificant_zeros => true)
 # => 13

 number_with_precision(389.32314, :precision => 4, :significant => true)    # => 389.3
 number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
 # => 1.111,23
     # File lib/action_view/helpers/number_helper.rb, line 316
316:       def number_with_precision(number, options = {})
317:         options.symbolize_keys!
318: 
319:         number = begin
320:           Float(number)
321:         rescue ArgumentError, TypeError
322:           if options[:raise]
323:             raise InvalidNumberError, number
324:           else
325:             return number
326:           end
327:         end
328: 
329:         defaults           = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
330:         precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
331:         defaults           = defaults.merge(precision_defaults)
332: 
333:         options = options.reverse_merge(defaults)  # Allow the user to unset default values: Eg.: :significant => false
334:         precision = options.delete :precision
335:         significant = options.delete :significant
336:         strip_insignificant_zeros = options.delete :strip_insignificant_zeros
337: 
338:         if significant and precision > 0
339:           if number == 0
340:             digits, rounded_number = 1, 0
341:           else
342:             digits = (Math.log10(number.abs) + 1).floor
343:             rounded_number = (BigDecimal.new(number.to_s) / BigDecimal.new((10 ** (digits - precision)).to_f.to_s)).round.to_f * 10 ** (digits - precision)
344:             digits = (Math.log10(rounded_number.abs) + 1).floor # After rounding, the number of digits may have changed
345:           end
346:           precision -= digits
347:           precision = precision > 0 ? precision : 0  #don't let it be negative
348:         else
349:           rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
350:         end
351:         formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options)
352:         if strip_insignificant_zeros
353:           escaped_separator = Regexp.escape(options[:separator])
354:           formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe
355:         else
356:           formatted_number
357:         end
358: 
359:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.