Skip to content

Instantly share code, notes, and snippets.

@lanqy
Created March 19, 2013 03:05
Embed
What would you like to do?
JavaScript To Convert Bytes To MB, KB, Etc
// from http://scratch99.com/web-development/javascript/convert-bytes-to-mb-kb/
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
if (i == 0) return bytes + ' ' + sizes[i];
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
@pe77
Copy link

pe77 commented Nov 24, 2015

Nice

@williamoliveira
Copy link

ES6 and airbnb's eslint compliant version:

function bytesToSize(bytes) {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  if (bytes === 0) return 'n/a'
  const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10)
  if (i === 0) return `${bytes} ${sizes[i]})`
  return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`
}

@Oluwasetemi
Copy link

function bytesToSize(bytes) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
if (bytes === 0) return 'n/a'
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10)
if (i === 0) return ${bytes} ${sizes[i]})
return ${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}
}

@deathwebo
Copy link

With little typo fixed on line 5:

function bytesToSize(bytes) {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  if (bytes === 0) return 'n/a'
  const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10)
  if (i === 0) return `${bytes} ${sizes[i]}`
  return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`
}

@seahindeniz
Copy link

seahindeniz commented Dec 24, 2018

Some may doesn't like having a seperator so:

function bytesToSize(bytes, seperator = "") {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  if (bytes == 0) return 'n/a'
  const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10)
  if (i === 0) return `${bytes}${seperator}${sizes[i]}`
  return `${(bytes / (1024 ** i)).toFixed(1)}${seperator}${sizes[i]}`
}

console.log( bytesToSize(2659633) ); // 2.5MB
console.log( bytesToSize(2659633, " ") ); // 2.5 MB
console.log( bytesToSize(2659633, "-") ); // 2.5-MB

@jedfoster
Copy link

jedfoster commented Jan 3, 2019

I had a need to format negative values, but Math.log(x) returns NaN if x is negative, so I pass bytes through Math.abs() first.

function bytesToSize(bytes) {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return 'n/a';
  const i = parseInt(Math.floor(Math.log(Math.abs(bytes)) / Math.log(1024)), 10);
  if (i === 0) return `${bytes} ${sizes[i]}`;
  return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`;
}

console.log(bytesToSize(1234567)); // 1.2 MB
console.log(bytesToSize(-1234567)); // -1.2 MB

@jzombie
Copy link

jzombie commented Oct 17, 2019

@jedfoster I used your code, but just pointing out something... If you're only rendering "Bytes", there's a dangling closing parenthesis.

e.g. "Bytes)"

@StasAreshin
Copy link

StasAreshin commented Jan 13, 2020

  • 1 redundant line removed
  • added suffix param
  • fixed error if size more then 1023 TB
function prettySize(bytes, separator = '', postFix = '') {
    if (bytes) {
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.min(parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10), sizes.length - 1);
        return `${(bytes / (1024 ** i)).toFixed(i ? 1 : 0)}${separator}${sizes[i]}${postFix}`;
    }
    return 'n/a';
}

@Akifcan
Copy link

Akifcan commented Feb 3, 2020

thank you

@ZachMoreno
Copy link

fixed a type error on line 4, Argument of type 'number' is not assignable to parameter of type 'string'

prettySize(bytes, separator = '', postFix = '') {
    if (bytes) {
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.min(parseInt(Math.floor(Math.log(bytes) / Math.log(1024)).toString(), 10), sizes.length - 1);
        return `${(bytes / (1024 ** i)).toFixed(i ? 1 : 0)}${separator}${sizes[i]}${postFix}`;
    }
    return 'n/a';
}

@zackster
Copy link

zackster commented Apr 14, 2020

A little bit of code for people who want the reverse.
Basically adapted this from https://stackoverflow.com/a/31625253/104461

function printpower (n, base, power) {
  if (base === 2) { // 1 << power is approx 10x faster than Math.pow(2, power) 
    console.log(n * (1 << power))
  } else {
    console.log(n * Math.pow(base, power))
  }
}

const humanReadable = '86 MB'

const [n, abbreviation] = humanReadable.split(/\s+/)
if (abbreviation) {
  if (/K(iB)?$/.test(abbreviation)) {
    printpower(n, 2, 10)
  } else if (/M(iB)?$/.test(abbreviation)) {
    printpower(n, 2, 20)
  } else if (/G(iB)?$/.test(abbreviation)) {
    printpower(n, 2, 30)
  } else if (/T(iB)?$/.test(abbreviation)) {
    printpower(n, 2, 40)
  } else if (/KB$/.test(abbreviation)) {
    printpower(n, 10, 3)
  } else if (/MB$/.test(abbreviation)) {
    printpower(n, 10, 6)
  } else if (/GB$/.test(abbreviation)) {
    printpower(n, 10, 9)
  } else if (/TB$/.test(abbreviation)) {
    printpower(n, 10, 12)
  }
} else {
  console.log(n)
}

Edit: the if statement is probably pretty expensive, and so are the Regular Expressions (at a minimum, should be compiled once as const variables), so there is room for incremental optimization!

@tobiasalbirosa
Copy link

Thanks all of you

@ahmnouira
Copy link

TypeScript version:

export function bytesToSize(bytes: number): string {
  const sizes: string[] = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  if (bytes === 0) return 'n/a'
  const i: number = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)).toString())
  if (i === 0) return `${bytes} ${sizes[i]}`
  return `${(bytes / Math.pow(1024, i)).toFixed(1)} ${sizes[i]}`
}

@trankov
Copy link

trankov commented Jul 14, 2021

Strength and power of open source community. I'm shocked and impressed. Thanks to all, guys.

@denik1981
Copy link

denik1981 commented Aug 27, 2021

function bytesToSize(bytes) {
  const units = ["byte", "kilobyte", "megabyte", "terabyte", "petabyte"];
  const unit = Math.floor(Math.log(bytes) / Math.log(1024));
  return new Intl.NumberFormat("en", {style: "unit", unit: units[unit]}).format(bytes / 1024 ** unit);
}

@rmorlok
Copy link

rmorlok commented Jul 8, 2022

To expand on the typescript version, I don't think the parseInt(...) is required. Also, in the unlikely case that you exceed 999.9 TB, you end up in xxx.x undefined territory.

Here is a fixed Typescript version:

export function bytesToSize(bytes: number): string {
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return 'n/a';
  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), sizes.length - 1);
  if (i === 0) return `${bytes} ${sizes[i]}`;
  return `${(bytes / (1024 ** i)).toFixed(1)} ${sizes[i]}`;
}

With Jest spec:

describe('bytesToSize', () => {
  test.each([
    [0, 'n/a'],
    [1, '1 Bytes'],
    [2000, '2.0 KB'],
    [30000, '29.3 KB'],
    [400000, '390.6 KB'],
    [5000000, '4.8 MB'],
    [60000000, '57.2 MB'],
    [700000000, '667.6 MB'],
    [8000000000, '7.5 GB'],
    [90000000000, '83.8 GB'],
    [100000000000, '93.1 GB'],
    [1100000000000, '1.0 TB'],
    [12000000000000, '10.9 TB'],
    [130000000000000, '118.2 TB'],
    [1400000000000000, '1273.3 TB'],
    [15000000000000000, '13642.4 TB'],
  ])('.bytesToSize(%p)', (
    val: number,
    expected: string,
  ) => {
    expect(
      bytesToSize(val),
    ).toBe(expected);
  });
});

@Dymerz
Copy link

Dymerz commented Nov 23, 2022

Using the Intl.NumberFormat for local friendly conversions

export function bytesToSize(bytes: number): string {
  const units = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte'];

  const navigatorLocal = navigator.languages && navigator.languages.length >= 0 ? navigator.languages[0] : 'en-US'
  const unitIndex      = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1));

  return Intl.NumberFormat(navigatorLocal, {
    style: 'unit',
    unit : units[unitIndex]
  }).format(bytes / (1024 ** unitIndex))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment