github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/humanized-duration.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "fmt" 22 "math" 23 "time" 24 ) 25 26 // humanizedDuration container to capture humanized time. 27 type humanizedDuration struct { 28 Days int64 `json:"days,omitempty"` 29 Hours int64 `json:"hours,omitempty"` 30 Minutes int64 `json:"minutes,omitempty"` 31 Seconds int64 `json:"seconds,omitempty"` 32 MilliSeconds int64 `json:"milliSeconds,omitempty"` 33 } 34 35 // StringShort() humanizes humanizedDuration to human readable short format. 36 // This does not print at seconds. 37 func (r humanizedDuration) StringShort() string { 38 switch { 39 case r.Days == 0 && r.Hours == 0 && r.Minutes == 0 && r.Seconds == 0: 40 return fmt.Sprintf("%d milliseconds", r.MilliSeconds) 41 case r.Days == 0 && r.Hours == 0 && r.Minutes == 0: 42 return fmt.Sprintf("%d seconds", r.Seconds) 43 case r.Days == 0 && r.Hours == 0: 44 return fmt.Sprintf("%d minutes", r.Minutes) 45 case r.Days == 0: 46 return fmt.Sprintf("%d hours %d minutes", r.Hours, r.Minutes) 47 case r.Days <= 2: 48 return fmt.Sprintf("%d days, %d hours", r.Days, r.Hours) 49 default: 50 return fmt.Sprintf("%d days", r.Days) 51 } 52 } 53 54 // String() humanizes humanizedDuration to human readable, 55 func (r humanizedDuration) String() string { 56 if r.Days == 0 && r.Hours == 0 && r.Minutes == 0 && r.Seconds == 0 { 57 return fmt.Sprintf("%d milliseconds", r.MilliSeconds) 58 } 59 60 if r.Days == 0 && r.Hours == 0 && r.Minutes == 0 { 61 return fmt.Sprintf("%d seconds", r.Seconds) 62 } 63 if r.Days == 0 && r.Hours == 0 { 64 return fmt.Sprintf("%d minutes %d seconds", r.Minutes, r.Seconds) 65 } 66 if r.Days == 0 { 67 return fmt.Sprintf("%d hours %d minutes %d seconds", r.Hours, r.Minutes, r.Seconds) 68 } 69 return fmt.Sprintf("%d days %d hours %d minutes %d seconds", r.Days, r.Hours, r.Minutes, r.Seconds) 70 } 71 72 // timeDurationToHumanizedDuration convert golang time.Duration to a custom more readable humanizedDuration. 73 func timeDurationToHumanizedDuration(duration time.Duration) humanizedDuration { 74 r := humanizedDuration{} 75 if duration.Milliseconds() < 1000 { 76 r.MilliSeconds = int64(duration.Milliseconds()) 77 return r 78 } 79 if duration.Seconds() < 60.0 { 80 r.Seconds = int64(duration.Seconds()) 81 return r 82 } 83 if duration.Minutes() < 60.0 { 84 remainingSeconds := math.Mod(duration.Seconds(), 60) 85 r.Seconds = int64(remainingSeconds) 86 r.Minutes = int64(duration.Minutes()) 87 return r 88 } 89 if duration.Hours() < 24.0 { 90 remainingMinutes := math.Mod(duration.Minutes(), 60) 91 remainingSeconds := math.Mod(duration.Seconds(), 60) 92 r.Seconds = int64(remainingSeconds) 93 r.Minutes = int64(remainingMinutes) 94 r.Hours = int64(duration.Hours()) 95 return r 96 } 97 remainingHours := math.Mod(duration.Hours(), 24) 98 remainingMinutes := math.Mod(duration.Minutes(), 60) 99 remainingSeconds := math.Mod(duration.Seconds(), 60) 100 r.Hours = int64(remainingHours) 101 r.Minutes = int64(remainingMinutes) 102 r.Seconds = int64(remainingSeconds) 103 r.Days = int64(duration.Hours() / 24) 104 return r 105 }