33 lines
1.0 KiB
PHP
33 lines
1.0 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
/**
|
|
* Byte counts for humans. WireGuard reports raw octets, and an operator
|
|
* scanning a table needs "1,4 GB", not 1503238553.
|
|
*/
|
|
final class Bytes
|
|
{
|
|
/**
|
|
* Decimal units (1 kB = 1000 B), not binary ones. Traffic and storage are
|
|
* sold in SI gigabytes — by us and by Hetzner — so a 1000 GB allowance has
|
|
* to read as "1 TB" and not as "931 GB", which is what dividing by 1024
|
|
* produced.
|
|
*/
|
|
public static function human(int $bytes, int $decimals = 1): string
|
|
{
|
|
if ($bytes < 1000) {
|
|
return $bytes.' B';
|
|
}
|
|
|
|
$units = ['kB', 'MB', 'GB', 'TB', 'PB'];
|
|
$power = min((int) floor(log($bytes, 1000)), count($units));
|
|
$value = $bytes / (1000 ** $power);
|
|
|
|
// Whole numbers read better without a trailing ",0" — "1 TB", not "1,0 TB".
|
|
$decimals = ($value >= 100 || round($value, $decimals) == floor($value)) ? 0 : $decimals;
|
|
|
|
return number_format($value, $decimals, ',', '.').' '.$units[$power - 1];
|
|
}
|
|
}
|