github.com/tawesoft/golib/v2@v2.10.0/legacy/humanize/format.go (about) 1 package humanize 2 3 import ( 4 "math" 5 "strings" 6 ) 7 8 // FormatParts is a general purpose locale-aware way to format any quantity 9 // with a defined set of factors into a list of parts. The unit argument is the 10 // base unit e.g. s for seconds, m for meters, B for bytes. In the simple case 11 // a list of only one Part is returned, e.g. a Part representing 1.5 km. In 12 // other cases, there may be multiple parts e.g. the two parts "1 h" and 13 // "30 min" making up the time "1 h 30 min". The number of parts returned is 14 // never more than that defined by the factors argument's Components field 15 // (but may be fewer). 16 func FormatParts(n float64, unit Unit, factors Factors) []Part { 17 18 numComponents := factors.Components 19 if numComponents == 0 { numComponents = 1 } 20 21 parts := make([]Part, 0, numComponents) 22 23 for i := 0; i < numComponents; i++ { 24 factorIdx := factors.Min(n) 25 factor := factors.Factors[factorIdx] 26 27 part := Part{ 28 Magnitude: n / factor.Magnitude, 29 Unit: factor.Unit, 30 } 31 32 // skip if not the only non-zero component, but zero magnitude 33 const epsilon = 0.01 34 if (part.Magnitude < epsilon) && (len(parts) > 0) { 35 continue 36 } 37 38 if i == numComponents - 1 { // last? 39 if factor.Mode & FactorModeUnitPrefix == FactorModeUnitPrefix { 40 part.Unit = part.Unit.Cat(unit) 41 } else if factor.Mode & FactorModeReplace == FactorModeReplace { 42 part.Unit = factor.Unit 43 } else { 44 part.Unit = unit 45 } 46 } else { 47 int, frac := math.Modf(part.Magnitude) 48 part.Magnitude = int 49 n = frac * factor.Magnitude 50 } 51 52 parts = append(parts, part) 53 } 54 55 return parts 56 } 57 58 func (h *humanizer) Format(n float64, unit Unit, factors Factors) String { 59 resultUtf8 := make([]string, 0, factors.Components) 60 resultAscii := make([]string, 0, factors.Components) 61 parts := FormatParts(n, unit, factors) 62 63 for _, part := range parts { 64 65 places := 0 66 67 if part.Magnitude < 10.0 { 68 places = 1 69 } 70 71 if part.Magnitude < 1.0 { 72 places = 2 73 } 74 75 _, frac := math.Modf(part.Magnitude) 76 if math.Abs(frac) < 0.01 { 77 places = 0 78 } 79 80 str := h.Printer.Sprintf("%.*f", places, part.Magnitude) 81 resultUtf8 = append(resultUtf8, str, part.Unit.Utf8) 82 resultAscii = append(resultAscii, str, part.Unit.Ascii) 83 } 84 85 return String{ 86 strings.Join(resultUtf8, " "), 87 strings.Join(resultAscii, " "), 88 } 89 }