Method: ActionView::Helpers::NumberHelper#number_to_human_size

Defined in:
actionpack/lib/action_view/helpers/number_helper.rb

- (Object) number_to_human_size(number, options = {})

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)

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"


312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'actionpack/lib/action_view/helpers/number_helper.rb', line 312

def number_to_human_size(number, options = {})
  options.symbolize_keys!

  number = begin
    Float(number)
  rescue ArgumentError, TypeError
    if options[:raise]
      raise InvalidNumberError, number
    else
      return number
    end
  end

  defaults = I18n.translate(:number.format', :locale => options[:locale], :default => {})
  human    = I18n.translate(:number.human.format', :locale => options[:locale], :default => {})
  defaults = defaults.merge(human)

  options = options.reverse_merge(defaults)
  #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
  options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)

  storage_units_format = I18n.translate(:number.human.storage_units.format', :locale => options[:locale], :raise => true)

  if number.to_i < 1024
    unit = I18n.translate(:number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
    storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe
  else
    max_exp  = STORAGE_UNITS.size - 1
    exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
    exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
    number  /= 1024 ** exponent

    unit_key = STORAGE_UNITS[exponent]
    unit = I18n.translate(:number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)

    formatted_number = number_with_precision(number, options)
    storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe
  end
end

Comments