Skip to content

Instantly share code, notes, and snippets.

@jeremy-code
Created March 6, 2024 03:03
Show Gist options
  • Save jeremy-code/6005493a54fd023ce103024460c8b9ea to your computer and use it in GitHub Desktop.
Save jeremy-code/6005493a54fd023ce103024460c8b9ea to your computer and use it in GitHub Desktop.
formatBytes.ts, format bytes
export const formatBytes = (bytes: number, options?: Intl.NumberFormatOptions) => {
/**
* Per {@link https://tc39.es/ecma402/#table-sanctioned-single-unit-identifiers},
* these are the valid units for the "unit" style. Since each unit multiple is
* considered a separate unit, we have to manually determine the appropriate unit
* and corresponding value, otherwise we get formatting such as "1 BB" instead of
* "1 GB".
*/
const units = ["byte", "kilobyte", "megabyte", "gigabyte", "terabyte", "petabyte"];
if (!bytes || bytes <= 0) return `0 ${units[0]}s`;
// note, this is in base 10 and not base 2, so gigabyte = 1000 megabytes
const exponent = Math.min(Math.floor(Math.log10(bytes) / 3), units.length - 1);
const value = bytes / 1000 ** exponent;
return new Intl.NumberFormat(undefined, {
style: "unit",
unit: units[exponent],
unitDisplay: "long",
...options,
}).format(value);
};
@jeremy-code
Copy link
Author

jeremy-code commented Mar 6, 2024

behavior acts a bit funny when bytes isn't an integer, but not sure should happen with decimals (... 1 byte and 4 bits...? 1.5 bytes? just round down to 1 byte? not sure)

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