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 of the output string (defaults to “%u%n”). The field types are:
%u The currency unit %n 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, :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 106 106: def number_to_currency(number, options = {}) 107: return nil if number.nil? 108: 109: options.symbolize_keys! 110: 111: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 112: currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {}) 113: 114: defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency) 115: options = defaults.merge!(options) 116: 117: unit = options.delete(:unit) 118: format = options.delete(:format) 119: 120: begin 121: value = number_with_precision(number, options.merge(:raise => true)) 122: format.gsub(/%n/, value).gsub(/%u/, unit).html_safe 123: rescue InvalidNumberError => e 124: if options[:raise] 125: raise 126: else 127: formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit) 128: e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number 129: end 130: end 131: 132: 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 429 429: def number_to_human(number, options = {}) 430: options.symbolize_keys! 431: 432: number = begin 433: Float(number) 434: rescue ArgumentError, TypeError 435: if options[:raise] 436: raise InvalidNumberError, number 437: else 438: return number 439: end 440: end 441: 442: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 443: human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {}) 444: defaults = defaults.merge(human) 445: 446: options = options.reverse_merge(defaults) 447: #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files 448: options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros) 449: 450: units = options.delete :units 451: unit_exponents = case units 452: when Hash 453: units 454: when String, Symbol 455: I18n.translate(:"#{units}", :locale => options[:locale], :raise => true) 456: when nil 457: I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true) 458: else 459: raise ArgumentError, ":units must be a Hash or String translation scope." 460: end.keys.map{|e_name| DECIMAL_UNITS.invert[e_name] }.sort_by{|e| -e} 461: 462: number_exponent = Math.log10(number).floor 463: display_exponent = unit_exponents.find{|e| number_exponent >= e } 464: number /= 10 ** display_exponent 465: 466: unit = case units 467: when Hash 468: units[DECIMAL_UNITS[display_exponent]] 469: when String, Symbol 470: I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i) 471: else 472: I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i) 473: end 474: 475: decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u") 476: formatted_number = number_with_precision(number, options) 477: decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe 478: 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 312 312: def number_to_human_size(number, options = {}) 313: options.symbolize_keys! 314: 315: number = begin 316: Float(number) 317: rescue ArgumentError, TypeError 318: if options[:raise] 319: raise InvalidNumberError, number 320: else 321: return number 322: end 323: end 324: 325: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 326: human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {}) 327: defaults = defaults.merge(human) 328: 329: options = options.reverse_merge(defaults) 330: #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files 331: options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros) 332: 333: storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true) 334: 335: if number.to_i < 1024 336: unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true) 337: storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe 338: else 339: max_exp = STORAGE_UNITS.size - 1 340: exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024 341: exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit 342: number /= 1024 ** exponent 343: 344: unit_key = STORAGE_UNITS[exponent] 345: unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) 346: 347: formatted_number = number_with_precision(number, options) 348: storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe 349: end 350: 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 151 151: def number_to_percentage(number, options = {}) 152: return nil if number.nil? 153: 154: options.symbolize_keys! 155: 156: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 157: percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {}) 158: defaults = defaults.merge(percentage) 159: 160: options = options.reverse_merge(defaults) 161: 162: begin 163: "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe 164: rescue InvalidNumberError => e 165: if options[:raise] 166: raise 167: else 168: e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%" 169: end 170: end 171: 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 189 189: def number_with_delimiter(number, options = {}) 190: options.symbolize_keys! 191: 192: begin 193: Float(number) 194: rescue ArgumentError, TypeError 195: if options[:raise] 196: raise InvalidNumberError, number 197: else 198: return number 199: end 200: end 201: 202: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 203: options = options.reverse_merge(defaults) 204: 205: parts = number.to_s.split('.') 206: parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}") 207: parts.join(options[:separator]).html_safe 208: 209: 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 237 237: def number_with_precision(number, options = {}) 238: options.symbolize_keys! 239: 240: number = begin 241: Float(number) 242: rescue ArgumentError, TypeError 243: if options[:raise] 244: raise InvalidNumberError, number 245: else 246: return number 247: end 248: end 249: 250: defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {}) 251: precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {}) 252: defaults = defaults.merge(precision_defaults) 253: 254: options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false 255: precision = options.delete :precision 256: significant = options.delete :significant 257: strip_insignificant_zeros = options.delete :strip_insignificant_zeros 258: 259: if significant and precision > 0 260: if number == 0 261: digits, rounded_number = 1, 0 262: else 263: digits = (Math.log10(number) + 1).floor 264: rounded_number = BigDecimal.new((number / 10 ** (digits - precision)).to_s).round.to_f * 10 ** (digits - precision) 265: end 266: precision = precision - digits 267: precision = precision > 0 ? precision : 0 #don't let it be negative 268: else 269: rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision 270: end 271: formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options) 272: if strip_insignificant_zeros 273: escaped_separator = Regexp.escape(options[:separator]) 274: formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe 275: else 276: formatted_number 277: end 278: 279: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.