= 1024 && $i < count($units) - 1) { $bytes /= 1024; $i++; } return ($i === 0 ? (string)round($bytes) : number_format($bytes, $bytes >= 100 ? 0 : $decimals, '.', '')) . ' ' . $units[$i]; } /** "20261110T12:34:56Z" (XAPI) -> seconds since 1970, 0 for none */ public static function time(string $xapi): int { if ($xapi === '' || str_starts_with($xapi, '1970')) { return 0; } $t = strtotime(str_replace('T', ' ', rtrim($xapi, 'Z')) . ' UTC'); return $t === false ? 0 : $t; } /** A time of the logs: the same form for events and alerts, in the computer's time zone. */ public static function stamp(int $time): string { return $time <= 0 ? '' : date('M j, Y H:i:s', $time); } public static function date(string $xapi): string { $t = self::time($xapi); return $t === 0 ? 'Never' : date('M j, Y H:i:s', $t); } public static function duration(int $seconds): string { if ($seconds <= 0) { return ''; } $days = intdiv($seconds, 86400); $hours = intdiv($seconds % 86400, 3600); $minutes = intdiv($seconds % 3600, 60); $out = []; if ($days > 0) { $out[] = $days . ($days === 1 ? ' day' : ' days'); } if ($hours > 0) { $out[] = $hours . ($hours === 1 ? ' hour' : ' hours'); } if ($days === 0) { $out[] = $minutes . ($minutes === 1 ? ' minute' : ' minutes'); } return implode(' ', $out); } /** "2.4 GHz" from cpu_info speed "2394.454" (MHz) */ public static function mhz(string $speed): string { $mhz = (float)$speed; return $mhz >= 1000 ? number_format($mhz / 1000, 2) . ' GHz' : round($mhz) . ' MHz'; } }