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.
Formats a number into a currency string (e.g., $13.65). You can customize the format in the options hash.
: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 <tt>%u</tt> for the currency, and <tt>%n</tt> for the number.
:negative_format - Sets the format for negative numbers (defaults to prepending
an hyphen to the formatted number given by <tt>:format</tt>). Accepts the same fields than <tt>:format</tt>, except <tt>%n</tt> is here the absolute value of the number.
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,506 € number_to_currency(1234567890.50, :negative_format => "(%u%n)") # => ($1,234,567,890.51) 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 111 111: def number_to_currency(number, options = {}) 112: return nil if number.nil? 113: 114: options.symbolize_keys! 115: 116: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 117: currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {}) 118: 119: defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency) 120: defaults[:negative_format] = "-" + options[:format] if options[:format] 121: options = defaults.merge!(options) 122: 123: unit = options.delete(:unit) 124: format = options.delete(:format) 125: 126: if number.to_f < 0 127: format = options.delete(:negative_format) 128: number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '') 129: end 130: 131: begin 132: value = number_with_precision(number, options.merge(:raise => true)) 133: format.gsub(/%n/, value).gsub(/%u/, unit).html_safe 134: rescue InvalidNumberError => e 135: if options[:raise] 136: raise 137: else 138: formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit) 139: e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number 140: end 141: end 142: 143: end
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 mililiters”, etc). You may define a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).
: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
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"
Unsignificant 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"
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: "gazilion-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 gazilion-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 440 440: def number_to_human(number, options = {}) 441: options.symbolize_keys! 442: 443: number = begin 444: Float(number) 445: rescue ArgumentError, TypeError 446: if options[:raise] 447: raise InvalidNumberError, number 448: else 449: return number 450: end 451: end 452: 453: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 454: human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {}) 455: defaults = defaults.merge(human) 456: 457: options = options.reverse_merge(defaults) 458: #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files 459: options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros) 460: 461: units = options.delete :units 462: unit_exponents = case units 463: when Hash 464: units 465: when String, Symbol 466: I18n.translate(:"#{units}", :locale => options[:locale], :raise => true) 467: when nil 468: I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true) 469: else 470: raise ArgumentError, ":units must be a Hash or String translation scope." 471: end.keys.map{|e_name| DECIMAL_UNITS.invert[e_name] }.sort_by{|e| -e} 472: 473: number_exponent = number != 0 ? Math.log10(number.abs).floor : 0 474: display_exponent = unit_exponents.find{|e| number_exponent >= e } 475: number /= 10 ** display_exponent 476: 477: unit = case units 478: when Hash 479: units[DECIMAL_UNITS[display_exponent]] 480: when String, Symbol 481: I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i) 482: else 483: I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i) 484: end 485: 486: decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u") 487: formatted_number = number_with_precision(number, options) 488: decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe 489: end
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.
: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)
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 323 323: def number_to_human_size(number, options = {}) 324: options.symbolize_keys! 325: 326: number = begin 327: Float(number) 328: rescue ArgumentError, TypeError 329: if options[:raise] 330: raise InvalidNumberError, number 331: else 332: return number 333: end 334: end 335: 336: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 337: human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {}) 338: defaults = defaults.merge(human) 339: 340: options = options.reverse_merge(defaults) 341: #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files 342: options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros) 343: 344: storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true) 345: 346: if number.to_i < 1024 347: unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true) 348: storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe 349: else 350: max_exp = STORAGE_UNITS.size - 1 351: exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024 352: exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit 353: number /= 1024 ** exponent 354: 355: unit_key = STORAGE_UNITS[exponent] 356: unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) 357: 358: formatted_number = number_with_precision(number, options) 359: storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe 360: end 361: end
Formats a number as a percentage string (e.g., 65%). You can customize the format in the options hash.
: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)
number_to_percentage(100) # => 100.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%
# File lib/action_view/helpers/number_helper.rb, line 162 162: def number_to_percentage(number, options = {}) 163: return nil if number.nil? 164: 165: options.symbolize_keys! 166: 167: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 168: percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {}) 169: defaults = defaults.merge(percentage) 170: 171: options = options.reverse_merge(defaults) 172: 173: begin 174: "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe 175: rescue InvalidNumberError => e 176: if options[:raise] 177: raise 178: else 179: e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%" 180: end 181: end 182: end
Formats a number into a US phone number (e.g., (555) 123-9876). You can customize the format in the options hash.
: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.
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(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".") => +1.123.555.1234 x 1343
# File lib/action_view/helpers/number_helper.rb, line 49 49: def number_to_phone(number, options = {}) 50: return nil if number.nil? 51: 52: begin 53: Float(number) 54: is_number_html_safe = true 55: rescue ArgumentError, TypeError 56: if options[:raise] 57: raise InvalidNumberError, number 58: else 59: is_number_html_safe = number.to_s.html_safe? 60: end 61: end 62: 63: number = number.to_s.strip 64: options = options.symbolize_keys 65: area_code = options[:area_code] || nil 66: delimiter = options[:delimiter] || "-" 67: extension = options[:extension].to_s.strip || nil 68: country_code = options[:country_code] || nil 69: 70: str = "" 71: str << "+#{country_code}#{delimiter}" unless country_code.blank? 72: str << if area_code 73: number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") 74: else 75: number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") 76: number.starts_with?('-') ? number.slice!(1..1) : number 77: end 78: str << " x #{extension}" unless extension.blank? 79: is_number_html_safe ? str.html_safe : str 80: end
Formats a number with grouped thousands using delimiter (e.g., 12,324). You can customize the format in the options hash.
: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 “.”).
number_with_delimiter(12345678) # => 12,345,678 number_with_delimiter(12345678.05) # => 12,345,678.05 number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678 number_with_delimiter(12345678, :separator => ",") # => 12,345,678 number_with_delimiter(12345678.05, :locale => :fr) # => 12 345 678,05 number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",") # => 98 765 432,98
# File lib/action_view/helpers/number_helper.rb, line 200 200: def number_with_delimiter(number, options = {}) 201: options.symbolize_keys! 202: 203: begin 204: Float(number) 205: rescue ArgumentError, TypeError 206: if options[:raise] 207: raise InvalidNumberError, number 208: else 209: return number 210: end 211: end 212: 213: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 214: options = options.reverse_merge(defaults) 215: 216: parts = number.to_s.split('.') 217: parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}") 218: parts.join(options[:separator]).html_safe 219: 220: end
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.
: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)
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 248 248: def number_with_precision(number, options = {}) 249: options.symbolize_keys! 250: 251: number = begin 252: Float(number) 253: rescue ArgumentError, TypeError 254: if options[:raise] 255: raise InvalidNumberError, number 256: else 257: return number 258: end 259: end 260: 261: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 262: precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {}) 263: defaults = defaults.merge(precision_defaults) 264: 265: options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false 266: precision = options.delete :precision 267: significant = options.delete :significant 268: strip_insignificant_zeros = options.delete :strip_insignificant_zeros 269: 270: if significant and precision > 0 271: if number == 0 272: digits, rounded_number = 1, 0 273: else 274: digits = (Math.log10(number.abs) + 1).floor 275: rounded_number = BigDecimal.new((number / 10 ** (digits - precision)).to_s).round.to_f * 10 ** (digits - precision) 276: end 277: precision = precision - digits 278: precision = precision > 0 ? precision : 0 #don't let it be negative 279: else 280: rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision 281: end 282: formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options) 283: if strip_insignificant_zeros 284: escaped_separator = Regexp.escape(options[:separator]) 285: formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe 286: else 287: formatted_number 288: end 289: 290: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.