Parse currency / float string to float type based on locale in go

Viewed 5341

I am puzzled how to parse a "float-string" to a float, based on knowing the i18n-locale but not making presumptions about the string.

Example: Germans, like me, write "1.234,87" when Americans write "1,234.87". In my project I do know what locale I do expect, but I do not want to "hard code" what presumptions I have about how that local writes that stuff.

I would hate to do regexp/stringreplacements.

Is there a generic way to say something like

myFloat := ParseFloatByLocale("1.234,76", "DE-DE")
// myFloat => 1234.76

strconvdoesn't seem to have this functionality, neither does x/text/language

Grateful for any hints!

2 Answers

/x/text unfortunately doesn't (publicly) expose everything you need for this, but I was able to leverage it to build something that works pretty well and integrates with /x/text for picking locale

// Locale-aware number parsing with lxstrconv
//
// Docs: https://godoc.org/tawesoft.co.uk/go/lxstrconv

package main

import (
    "fmt"
    "golang.org/x/text/language"
    "tawesoft.co.uk/go/lxstrconv"
)

func checked(f float64, e error) float64 {
    if e != nil {
        panic(e)
    }
    return f
}

func main() {
    dutch   := lxstrconv.NewDecimalFormat(language.Dutch)
    british := lxstrconv.NewDecimalFormat(language.BritishEnglish)
    arabic  := lxstrconv.NewDecimalFormat(language.Arabic)

    fmt.Printf("%f\n", checked(british.ParseFloat("1,234.56")))
    fmt.Printf("%f\n", checked(dutch.ParseFloat("1.234,56")))
    fmt.Printf("%f\n", checked(arabic.ParseFloat("١٬٢٣٤٫٥٦")))
}
Related