package reports import ( "fmt" "strconv" "strings" "time" ) // FormatBytes stellt eine Datenmenge lesbar dar. // // Binaerpraefixe, weil Speicher so verkauft und angezeigt wird und ein Bericht // nicht gegen die Anzeige des Betriebssystems arbeiten soll. func FormatBytes(byteCount float64) string { const unitStep = 1024.0 if byteCount < unitStep { return fmt.Sprintf("%.0f B", byteCount) } unitNames := []string{"KiB", "MiB", "GiB", "TiB", "PiB"} scaledValue := byteCount / unitStep for _, unitName := range unitNames { if scaledValue < unitStep { return fmt.Sprintf("%.1f %s", scaledValue, unitName) } scaledValue /= unitStep } return fmt.Sprintf("%.1f EiB", scaledValue) } // FormatDuration stellt eine Dauer in Sekunden lesbar dar. func FormatDuration(seconds float64) string { if seconds < 1 { return fmt.Sprintf("%.0f ms", seconds*1000) } wholeDuration := time.Duration(seconds * float64(time.Second)) switch { case wholeDuration < time.Minute: return fmt.Sprintf("%.1f s", seconds) case wholeDuration < time.Hour: return fmt.Sprintf("%d min %d s", int(wholeDuration.Minutes()), int(wholeDuration.Seconds())%60) case wholeDuration < 24*time.Hour: return fmt.Sprintf("%d h %d min", int(wholeDuration.Hours()), int(wholeDuration.Minutes())%60) default: return fmt.Sprintf("%d Tage %d h", int(wholeDuration.Hours())/24, int(wholeDuration.Hours())%24) } } // FormatPercent stellt einen Anteil dar. // // Ein kleiner Wert wird als „< 0,1 %" ausgewiesen, nicht als „0,0 %": Null // Prozent liest sich wie „nichts vorhanden" — dieselbe Regel wie in der // Uebersicht (Phase 12). func FormatPercent(percentValue float64) string { if percentValue > 0 && percentValue < 0.1 { return "< 0,1 %" } return strings.Replace(fmt.Sprintf("%.1f %%", percentValue), ".", ",", 1) } // FormatTimestamp stellt einen Zeitpunkt in UTC dar. // // Immer mit ausgeschriebener Zeitzone: Ein Bericht wandert zwischen Standorten, // und „14:00" ohne Zone hat je nach Leser drei Bedeutungen. func FormatTimestamp(pointInTime time.Time) string { return pointInTime.UTC().Format("2006-01-02 15:04:05 UTC") } // trimNumber stellt eine Zahl ohne ueberfluessige Nachkommastellen dar. func trimNumber(numericValue float64) string { return strconv.FormatFloat(numericValue, 'f', -1, 64) }