summaryrefslogtreecommitdiff
path: root/format.go
blob: 644ec46447bb165b8bc212f6848119f23ef4aea7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package float

import (
	"strconv"
	"strings"
)

func split(s string, n int) (ret []string) {
	var pos int
	if rest := len(s) % n; rest > 0 {
		ret = append(ret, s[:rest])
		pos = rest
	}
	for pos < len(s) {
		ret = append(ret, s[pos:pos+n])
		pos += n
	}
	return ret
}

func fill(s string, n int) string {
	if len(s) >= n {
		return s[:n]
	}
	return s + strings.Repeat("0", n-len(s))
}

// Country settings
type Country struct {
	Thousend, Decimal rune // delimiter rune
	Block, Fraction   int  // block length
}

const (
	Space        = ' '
	Apostrophe   = '\''
	Comma        = ','
	FullStop     = '.'
	MiddleDot    = '\u00b7'
	ThinSpace    = '\u2009'
	NoBreakSpace = '\u202f'
	DotAbove     = '\u02d9'
)

var (
	EN = Country{Space, FullStop, 3, 2} // SI EN
	FR = Country{Space, Comma, 3, 2}    // SI FR
	US = Country{Comma, FullStop, 3, 2}
	DE = Country{FullStop, Comma, 3, 2}
	IR = Country{Space, MiddleDot, 3, 2}
	CH = Country{Apostrophe, FullStop, 3, 2}
	IT = Country{DotAbove, Comma, 3, 2}
	CN = Country{Comma, FullStop, 4, 2} // 10000 based
)

// DefaultFormat is europeian SI format
var DefaultFormat = FR

// Format float value as localized representation
func (c Country) Format(v float64) string {
	s := strconv.FormatFloat(v, 'f', -1, 64)
	neg := strings.HasPrefix(s, "-")
	if neg {
		s = s[1:]
	}
	parts := strings.Split(s, ".")
	if len(parts) == 1 {
		parts = append(parts, "")
	}
	lhs := split(parts[0], c.Block)
	rhs := fill(parts[1], c.Fraction)
	s = strings.Join(lhs, string(c.Thousend))
	if neg {
		s = "-" + s
	}
	return s + string(c.Decimal) + rhs
}

// Format float with default format
func Format(v float64) string {
	return DefaultFormat.Format(v)
}