accounting

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 18, 2019 License: MIT Imports: 9 Imported by: 245

README

accounting - money and currency formatting for golang

Build Status Coverage Status GoDoc

accounting is a library for money and currency formatting. (inspired by accounting.js)

Quick Start

go get github.com/leekchan/accounting

example.go

package main

import (
    "fmt"
    "math/big"

    "github.com/shopspring/decimal"
    "github.com/leekchan/accounting"
)

func main() {
    ac := accounting.Accounting{Symbol: "$", Precision: 2}
    fmt.Println(ac.FormatMoney(123456789.213123))                       // "$123,456,789.21"
    fmt.Println(ac.FormatMoney(12345678))                               // "$12,345,678.00"
    fmt.Println(ac.FormatMoney(big.NewRat(77777777, 3)))                // "$25,925,925.67"
    fmt.Println(ac.FormatMoney(big.NewRat(-77777777, 3)))               // "-$25,925,925.67"
    fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(123456789.213123))) // "$123,456,789.21"
    fmt.Println(ac.FormatMoneyDecimal(decimal.New(123456789.213123, 0))) // "$123,456,789.21"

    ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
    fmt.Println(ac.FormatMoney(4999.99))  // "€4.999,99"

    // Or retrieve currency info from Locale struct
    lc := LocaleInfo["USD"]
    ac = accounting.Accounting{Symbol: lc.ComSymbol, Precision: 2, Thousand: lc.ThouSep, Decimal: lc.DecSep}
    fmt.Println(ac.FormatMoney(500000)) // "$500,000.00"

    ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
    fmt.Println(ac.FormatMoney(500000)) // "£ 500,000"

    ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
        Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
    fmt.Println(ac.FormatMoney(1000000)) // "GBP 1,000,000"
    fmt.Println(ac.FormatMoney(-5000))   // "GBP (5,000)"
    fmt.Println(ac.FormatMoney(0))       // "GBP --"

    ac = accounting.DefaultAccounting("GBP", 2)
    fmt.Println(ac.FormatMoney(1000000)) // "GBP 1,000,000"
    fmt.Println(ac.FormatMoney(-5000))   // "GBP (5,000)"
    fmt.Println(ac.FormatMoney(0))       // "GBP --"

    ac = accounting.NewAccounting("GBP", 2, ",", ".", "%s %v", "%s (%v)", "%s --")
    fmt.Println(ac.FormatMoney(1000000)) // "GBP 1,000,000"
    fmt.Println(ac.FormatMoney(-5000))   // "GBP (5,000)"
    fmt.Println(ac.FormatMoney(0))       // "GBP --"
}

Caution

Please do not use float64 to count money. Floats can have errors when you perform operations on them. Using big.Rat (< Go 1.5) or big.Float (>= Go 1.5) is highly recommended. (accounting supports float64, but it is just for convenience.)

Initialization

Accounting struct
type Accounting struct {
    Symbol         string // currency symbol (required)
    Precision      int    // currency precision (decimal places) (optional / default: 0)
    Thousand       string // thousand separator (optional / default: ,)
    Decimal        string // decimal separator (optional / default: .)
    Format         string // simple format string allows control of symbol position (%v = value, %s = symbol) (default: %s%v)
    FormatNegative string // format string for negative values (optional / default: strings.Replace(strings.Replace(accounting.Format, "-", "", -1), "%v", "-%v", -1))
    FormatZero     string // format string for zero values (optional / default: Format)
}
Field Type Description Default Example
Symbol string currency symbol no default value $
Precision int currency precision (decimal places) 0 2
Thousand string thousand separator , .
Decimal string decimal separator . ,
Format string simple format string allows control of symbol position (%v = value, %s = symbol) %s%v %s %v
FormatNegative string format string for negative values strings.Replace(strings.Replace(accounting.Format, "-", "", -1), "%v", "-%v", -1)) %s (%v)
FormatZero string format string for zero values Format %s --

Examples:

# Via functions
ac := accounting.DefaultAccounting("$", 2)
ac := accounting.NewAccounting("$", 2, ",", ".", "%s %v", "%s (%v)", "%s --")

# Via Accounting struct
ac := accounting.Accounting{Symbol: "$", Precision: 2}

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
        Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}

SetThousandSeparator(str string)

SetThousandSeparator sets the separator for the thousands separation

SetDecimalSeparator(str string)

SetDecimalSeparator sets the separator for the decimal separation

SetFormat(str string)

SetFormat sets the Format default: %s%v (%s=Symbol;%v=Value)

SetFormatNegative(str string)

SetFormatNegative sets the Format for negative values default: -%s%v (%s=Symbol;%v=Value)

SetFormatZero(str string)

SetFormatZero sets the Format for zero values default: %s%v (%s=Symbol;%v=Value)

Locale struct
type Locale struct {
    Name           string // currency name
    FractionLength int    // default decimal length
    ThouSep        string // thousands seperator
    DecSep         string // decimal seperator
    SpaceSep       string // space seperator
    UTFSymbol      string // UTF symbol
    HTMLSymbol     string // HTML symbol
    ComSymbol      string // Common symbol
    Pre            bool   // symbol before or after currency
}
Field Type Description Default Example
Name string currency name no default value US Dollar
FractionLength int default precision (decimal places) no default value 2
ThouSep string thousand separator no default value ,
DecSep string decimal separator no default value .
SpaceSep string space separator no default value " "
UTFSymbol string UTF symbol no default value "0024"
HTMLSymbol string HTML symbol no default value "&#x0024"
ComSymbol string Common symbol no default value "$"
Pre bool symbol before currency no default value true

Example:

// LocaleInfo map[string]Locale

var lc Locale
if val, ok := LocaleInfo["USD"]; ok {
    lc = val
} else {
    panic("No Locale Info Found")
}

fmt.Println(lc.Name) // "US Dollar"
fmt.Println(lc.FractionLength) // 2
fmt.Println(lc.ThouSep) // ","
fmt.Println(lc.DecSep) // "."
fmt.Println(lc.SpaceSep) // ""
fmt.Println(lc.UTFSymbol) // "0024"
fmt.Println(lc.HTMLSymbol) // "&#x0024"
fmt.Println(lc.ComSymbol) // "$"
fmt.Println(lc.Pre) // true

There are currently 181 currencies supported in LocaleInfo

FormatMoney(value interface{}) string

FormatMoney is a function for formatting numbers as money values, with customisable currency symbol, precision (decimal places), and thousand/decimal separators.

FormatMoney supports various types of value by runtime reflection. If you don't need runtime type evaluation, please refer to FormatMoneyInt, FormatMoneyBigRat, FormatMoneyBigRat, or FormatMoneyFloat64.

  • supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, *big.Rat

Examples:

ac := accounting.Accounting{Symbol: "$", Precision: 2}
fmt.Println(ac.FormatMoney(123456789.213123))         // "$123,456,789.21"
fmt.Println(ac.FormatMoney(12345678))                 // "$12,345,678.00"
fmt.Println(ac.FormatMoney(big.NewRat(77777777, 3)))  // "$25,925,925.67"
fmt.Println(ac.FormatMoney(big.NewRat(-77777777, 3))) // "-$25,925,925.67"

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
fmt.Println(ac.FormatMoney(4999.99))  // "€4.999,99"

ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
fmt.Println(ac.FormatMoney(500000)) // "£ 500,000"

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
    Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
fmt.Println(ac.FormatMoney(1000000)) // "GBP 1,000,000"
fmt.Println(ac.FormatMoney(-5000))   // "GBP (5,000)"
fmt.Println(ac.FormatMoney(0))       // "GBP --"

FormatMoneyBigFloat(value *big.Float) string

(>= Go 1.5)

FormatMoneyBigFloat only supports *big.Float value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

Examples:

ac = accounting.Accounting{Symbol: "$", Precision: 2}
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(123456789.213123))) // "$123,456,789.21"
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(12345678)))         // "$12,345,678.00"

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(4999.99)))  // "€4.999,99"

ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(500000))) // "£ 500,000"

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
    Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(1000000))) // "GBP 1,000,000"
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(-5000)))   // "GBP (5,000)"
fmt.Println(ac.FormatMoneyBigFloat(big.NewFloat(0)))       // "GBP --"

FormatMoneyInt(value int) string

FormatMoneyInt only supports int value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

Examples:

ac = accounting.Accounting{Symbol: "$", Precision: 2}
fmt.Println(ac.FormatMoneyInt(12345678)) // "$12,345,678.00"

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
fmt.Println(ac.FormatMoneyInt(4999))  // "€4.999,00"

ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
fmt.Println(ac.FormatMoneyInt(500000)) // "£ 500,000"

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
    Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
fmt.Println(ac.FormatMoneyInt(1000000)) // "GBP 1,000,000"
fmt.Println(ac.FormatMoneyInt(-5000))   // "GBP (5,000)"
fmt.Println(ac.FormatMoneyInt(0))       // "GBP --"

FormatMoneyBigRat(value *big.Rat) string

FormatMoneyBigRat only supports *big.Rat value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

Examples:

ac = accounting.Accounting{Symbol: "$", Precision: 2}
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(77777777, 3)))  // "$25,925,925.67"
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(-77777777, 3))) // "-$25,925,925.67"

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(77777777, 3)))  // "€25.925.925,67"

ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(77777777, 3)))  // "£ 25,925,926"

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
    Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(77777777, 3)))  // "GBP 25,925,926"
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(-77777777, 3))) // "GBP (25,925,926)"
fmt.Println(ac.FormatMoneyBigRat(big.NewRat(0, 3)))         // "GBP --"

FormatMoneyFloat64(value float64) string

FormatMoneyFloat64 only supports float64 value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

Examples:

ac = accounting.Accounting{Symbol: "$", Precision: 2}
fmt.Println(ac.FormatMoneyFloat64(123456789.213123)) // "$123,456,789.21"
fmt.Println(ac.FormatMoneyFloat64(12345678))         // "$12,345,678.00"

ac = accounting.Accounting{Symbol: "€", Precision: 2, Thousand: ".", Decimal: ","}
fmt.Println(ac.FormatMoneyFloat64(4999.99))  // "€4.999,99"

ac = accounting.Accounting{Symbol: "£ ", Precision: 0}
fmt.Println(ac.FormatMoneyFloat64(500000)) // "£ 500,000"

ac = accounting.Accounting{Symbol: "GBP", Precision: 0,
    Format: "%s %v", FormatNegative: "%s (%v)", FormatZero: "%s --"}
fmt.Println(ac.FormatMoneyFloat64(1000000)) // "GBP 1,000,000"
fmt.Println(ac.FormatMoneyFloat64(-5000))   // "GBP (5,000)"
fmt.Println(ac.FormatMoneyFloat64(0))       // "GBP --"

FormatNumber(value interface{}, precision int, thousand string, decimal string) string

FormatNumber is a base function of the library which formats a number with custom precision and separators.

FormatNumber supports various types of value by runtime reflection. If you don't need runtime type evaluation, please refer to FormatNumberInt, FormatNumberBigRat, or FormatNumberFloat64.

  • supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, *big.Rat

Examples:

fmt.Println(accounting.FormatNumber(123456789.213123, 3, ",", ".")) // "123,456,789.213"
fmt.Println(accounting.FormatNumber(1000000, 3, " ", ","))          // "1 000 000,000"

FormatNumberBigFloat(value *big.Float, precision int, thousand string, decimal string) string

(>= Go 1.5)

FormatNumberBigFloat only supports *big.Float value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

fmt.Println(accounting.FormatNumberBigFloat(big.NewFloat(123456789.213123), 3, ",", ".")) // "123,456,789.213"

FormatNumberInt(value int, precision int, thousand string, decimal string) string

FormatNumberInt only supports int value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

fmt.Println(accounting.FormatNumberInt(123456789, 3, ",", ".")) // "123,456,789.000"

FormatNumberBigRat(value *big.Rat, precision int, thousand string, decimal string) string

FormatNumberBigRat only supports *big.Rat value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

fmt.Println(accounting.FormatNumberBigRat(big.NewRat(77777777, 3), 3, ",", ".")) // "25,925,925.667"

FormatNumberFloat64(value float64, precision int, thousand string, decimal string) string

FormatNumberFloat64 only supports float64 value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

fmt.Println(accounting.FormatNumberFloat64(123456789.213123, 3, ",", ".")) // "123,456,789.213"

FormatNumberDecimal(value decimal.Decimal, precision int, thousand string, decimal string) string

FormatNumberDecimal only supports decimal.Decimal value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

import "github.com/shopspring/decimal"
fmt.Println(accounting.FormatNumberBigDecimal(apd.New(apd.New(4999999, -3), 3, ",", ".")) // "4,999.999"

FormatNumberBigDecimal(value apd.Decimal, precision int, thousand string, decimal string) string

FormatNumberDecimal only supports apd.Decimal value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

Examples:

import "github.com/cockroachdb/apd"
fmt.Println(accounting.FormatNumberDecimal(decimal.New(123456789.213123,3), 3, ",", ".")) // "123,456,789.213"

UnformatNumber(number string, precision int, currency string) string

UnformatNumber is the inverse of FormatNumber. It strips out all currency formatting and returns the number with a point for the decimal seperator.

Examples:

fmt.Println(accounting.UnformatNumber("$45,000.50", 2, "USD")) // "45000.50"
fmt.Println(accounting.UnformatNumber("EUR 12.500,3474", 3, "EUR")) // "12500.347"

Documentation

Index

Constants

This section is empty.

Variables

View Source
var LocaleInfo map[string]Locale = map[string]Locale{}/* 182 elements not displayed */

Functions

func FormatNumber

func FormatNumber(value interface{}, precision int, thousand string, decimalStr string) string

FormatNumber is a base function of the library which formats a number with custom precision and separators. FormatNumber supports various types of value by runtime reflection. If you don't need runtime type evaluation, please refer to FormatNumberInt or FormatNumberFloat64. (supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, *big.Rat) (also supported value types : decimal.Decimal, *decimal.Decimal *apd.Decimal)

func FormatNumberBigDecimal

func FormatNumberBigDecimal(x *apd.Decimal, precision int, thousand string, decimalStr string) string

FormatNumberBigDecimal only supports *apd.Decimal value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func FormatNumberBigFloat

func FormatNumberBigFloat(x *big.Float, precision int, thousand string, decimal string) string

FormatNumberBigFloat only supports *big.Float value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func FormatNumberBigRat

func FormatNumberBigRat(x *big.Rat, precision int, thousand string, decimalStr string) string

FormatNumberBigRat only supports *big.Rat value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func FormatNumberDecimal

func FormatNumberDecimal(x decimal.Decimal, precision int, thousand string, decimalStr string) string

FormatNumberDecimal only supports decimal.Decimal value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func FormatNumberFloat64

func FormatNumberFloat64(x float64, precision int, thousand string, decimalStr string) string

FormatNumberFloat64 only supports float64 value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func FormatNumberInt

func FormatNumberInt(x int, precision int, thousand string, decimalStr string) string

FormatNumberInt only supports int value. It is faster than FormatNumber, because it does not do any runtime type evaluation.

func UnformatNumber

func UnformatNumber(n string, precision int, currency string) string

UnformatNumber takes a string of the number to strip currency info on and precision for decimals. It pulls the currency descripter from the LocaleInfo map and uses it to return an unformatted value based on thous sep and decimal sep

Types

type Accounting

type Accounting struct {
	Symbol         string // currency symbol (required)
	Precision      int    // currency precision (decimal places) (optional / default: 0)
	Thousand       string // thousand separator (optional / default: ,)
	Decimal        string // decimal separator (optional / default: .)
	Format         string // simple format string allows control of symbol position (%v = value, %s = symbol) (default: %s%v)
	FormatNegative string // format string for negative values (optional / default: strings.Replace(strings.Replace(accounting.Format, "-", "", -1), "%v", "-%v", -1))
	FormatZero     string // format string for zero values (optional / default: Format)
	// contains filtered or unexported fields
}

func DefaultAccounting

func DefaultAccounting(symbol string, precision int) *Accounting

DefaultAccounting returns the Accounting with default settings

func NewAccounting

func NewAccounting(symbol string, precision int, thousand, decimal, format, formatNegative, formatZero string) *Accounting

NewAccounting returns the Accounting with default settings

func (*Accounting) FormatMoney

func (accounting *Accounting) FormatMoney(value interface{}) string

FormatMoney is a function for formatting numbers as money values, with customisable currency symbol, precision (decimal places), and thousand/decimal separators. FormatMoney supports various types of value by runtime reflection. If you don't need runtime type evaluation, please refer to FormatMoneyInt or FormatMoneyFloat64. (supported value types : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, *big.Rat)

func (*Accounting) FormatMoneyBigDecimal

func (accounting *Accounting) FormatMoneyBigDecimal(value *apd.Decimal) string

FormatMoneyBigDecimal only supports *apd.Decimal value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

func (*Accounting) FormatMoneyBigFloat

func (accounting *Accounting) FormatMoneyBigFloat(value *big.Float) string

FormatMoneyBigFloat only supports *big.Float value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

func (*Accounting) FormatMoneyBigRat

func (accounting *Accounting) FormatMoneyBigRat(value *big.Rat) string

FormatMoneyBigRat only supports *big.Rat value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

func (*Accounting) FormatMoneyDecimal

func (accounting *Accounting) FormatMoneyDecimal(value decimal.Decimal) string

FormatMoneyDecimal only supports decimal.Decimal value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

func (*Accounting) FormatMoneyFloat64

func (accounting *Accounting) FormatMoneyFloat64(value float64) string

FormatMoneyFloat64 only supports float64 value. It is faster than FormatMoney, because it does not do any runtime type evaluation. (Caution: Please do not use float64 to count money. Floats can have errors when you perform operations on them. Using big.Rat is highly recommended.)

func (*Accounting) FormatMoneyInt

func (accounting *Accounting) FormatMoneyInt(value int) string

FormatMoneyInt only supports int type value. It is faster than FormatMoney, because it does not do any runtime type evaluation.

func (*Accounting) SetDecimalSeparator

func (accounting *Accounting) SetDecimalSeparator(str string)

SetDecimalSeparator sets the separator for the decimal separation

func (*Accounting) SetFormat

func (accounting *Accounting) SetFormat(str string)

SetFormat sets the Format default: %s%v (%s=Symbol;%v=Value)

func (*Accounting) SetFormatNegative

func (accounting *Accounting) SetFormatNegative(str string)

SetFormatNegative sets the Format for negative values default: -%s%v (%s=Symbol;%v=Value)

func (*Accounting) SetFormatZero

func (accounting *Accounting) SetFormatZero(str string)

SetFormatZero sets the Format for zero values default: %s%v (%s=Symbol;%v=Value)

func (*Accounting) SetThousandSeparator

func (accounting *Accounting) SetThousandSeparator(str string)

SetThousandSeparator sets the separator for the thousands separation

type Locale

type Locale struct {
	Name           string // currency name
	FractionLength int    // default decimal length
	ThouSep        string // thousands seperator
	DecSep         string // decimal seperator
	SpaceSep       string // space seperator
	UTFSymbol      string // UTF symbol
	HTMLSymbol     string // HTML symbol
	ComSymbol      string // Common symbol
	Pre            bool   // symbol before or after currency
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL