]> git.proxmox.com Git - pve-common.git/blob - src/PVE/Format.pm
format: handle undef, 0, and decimals in render_duration
[pve-common.git] / src / PVE / Format.pm
1 package PVE::Format;
2
3 use strict;
4 use warnings;
5
6 use POSIX qw(strftime round);
7 use PVE::JSONSchema;
8
9 use base 'Exporter';
10 our @EXPORT_OK = qw(
11 render_timestamp
12 render_timestamp_gmt
13 render_duration
14 render_fraction_as_percentage
15 render_bytes
16 );
17
18 sub render_timestamp {
19 my ($epoch) = @_;
20
21 # ISO 8601 date format
22 return strftime("%F %H:%M:%S", localtime($epoch));
23 }
24
25 sub render_timestamp_gmt {
26 my ($epoch) = @_;
27
28 # ISO 8601 date format, standard Greenwich time zone
29 return strftime("%F %H:%M:%S", gmtime($epoch));
30 }
31
32 sub render_duration {
33 my ($duration_in_seconds) = @_;
34
35 my $text = '';
36 my $rest = round($duration_in_seconds // 0);
37
38 return "0s" if !$rest;
39
40 my $step = sub {
41 my ($unit, $unitlength) = @_;
42
43 if ((my $v = int($rest/$unitlength)) > 0) {
44 $text .= " " if length($text);
45 $text .= "${v}${unit}";
46 $rest -= $v * $unitlength;
47 }
48 };
49
50 $step->('w', 7*24*3600);
51 $step->('d', 24*3600);
52 $step->('h', 3600);
53 $step->('m', 60);
54 $step->('s', 1);
55
56 return $text;
57 }
58
59 sub render_fraction_as_percentage {
60 my ($fraction) = @_;
61
62 return sprintf("%.2f%%", $fraction*100);
63 }
64
65 sub render_bytes {
66 my ($value, $precision) = @_;
67
68 my @units = qw(B KiB MiB GiB TiB PiB);
69
70 my $max_unit = 0;
71 if ($value > 1023) {
72 $max_unit = int(log($value)/log(1024));
73 $value /= 1024**($max_unit);
74 }
75 my $unit = $units[$max_unit];
76 return sprintf "%." . ($precision || 2) . "f $unit", $value;
77 }
78
79 1;