1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:generate go run gen.go gen_common.go -output tables.go
7 // Package currency contains currency-related functionality.
9 // NOTE: the formatting functionality is currently under development and may
10 // change without notice.
11 package currency // import "golang.org/x/text/currency"
17 "golang.org/x/text/internal/tag"
18 "golang.org/x/text/language"
22 // - language-specific currency names.
23 // - currency formatting.
24 // - currency information per region
25 // - register currency code (there are no private use area)
27 // TODO: remove Currency type from package language.
29 // Kind determines the rounding and rendering properties of a currency value.
32 // TODO: formatting type: standard, accounting. See CLDR.
38 standard rounding = iota
43 // Standard defines standard rounding and formatting for currencies.
44 Standard Kind = Kind{rounding: standard}
46 // Cash defines rounding and formatting standards for cash transactions.
47 Cash Kind = Kind{rounding: cash}
49 // Accounting defines rounding and formatting standards for accounting.
50 Accounting Kind = Kind{rounding: standard}
53 // Rounding reports the rounding characteristics for the given currency, where
54 // scale is the number of fractional decimals and increment is the number of
55 // units in terms of 10^(-scale) to which to round to.
56 func (k Kind) Rounding(cur Unit) (scale, increment int) {
57 info := currency.Elem(int(cur.index))[3]
64 return int(roundings[info].scale), int(roundings[info].increment)
67 // Unit is an ISO 4217 currency designator.
72 // String returns the ISO code of u.
73 func (u Unit) String() string {
77 return currency.Elem(int(u.index))[:3]
80 // Amount creates an Amount for the given currency unit and amount.
81 func (u Unit) Amount(amount interface{}) Amount {
82 // TODO: verify amount is a supported number type
83 return Amount{amount: amount, currency: u}
87 errSyntax = errors.New("currency: tag is not well-formed")
88 errValue = errors.New("currency: tag is not a recognized currency")
91 // ParseISO parses a 3-letter ISO 4217 currency code. It returns an error if s
92 // is not well-formed or not a recognized currency code.
93 func ParseISO(s string) (Unit, error) {
94 var buf [4]byte // Take one byte more to detect oversize keys.
95 key := buf[:copy(buf[:], s)]
96 if !tag.FixCase("XXX", key) {
97 return Unit{}, errSyntax
99 if i := currency.Index(key); i >= 0 {
103 return Unit{uint16(i)}, nil
105 return Unit{}, errValue
108 // MustParseISO is like ParseISO, but panics if the given currency unit
109 // cannot be parsed. It simplifies safe initialization of Unit values.
110 func MustParseISO(s string) Unit {
111 c, err := ParseISO(s)
118 // FromRegion reports the currency unit that is currently legal tender in the
119 // given region according to CLDR. It will return false if region currently does
120 // not have a legal tender.
121 func FromRegion(r language.Region) (currency Unit, ok bool) {
123 i := sort.Search(len(regionToCurrency), func(i int) bool {
124 return regionToCurrency[i].region >= x
126 if i < len(regionToCurrency) && regionToCurrency[i].region == x {
127 return Unit{regionToCurrency[i].code}, true
132 // FromTag reports the most likely currency for the given tag. It considers the
133 // currency defined in the -u extension and infers the region if necessary.
134 func FromTag(t language.Tag) (Unit, language.Confidence) {
135 if cur := t.TypeForKey("cu"); len(cur) == 3 {
136 c, _ := ParseISO(cur)
137 return c, language.Exact
139 r, conf := t.Region()
140 if cur, ok := FromRegion(r); ok {
143 return Unit{}, language.No
147 // Undefined and testing.
151 // G10 currencies https://en.wikipedia.org/wiki/G10_currencies.
163 // Additional common currencies as defined by CLDR.