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
strconv
doesn't seem to have this functionality, neither does x/text/language
Grateful for any hints!
Your best bet is the use the standard library's strconv
. You can make your own wrappers and locale stuff. Eventually I'd add more error checking and turn this into it's own package, but here is an idea. If you haven't found a package yet there is a good chance you will have to write your own. For a more general solution, you'd have to think about every possible input.. normalize that per locale and enforce those rules when others are using your tools... That would be a more complex solution given the number of if statements and pieces of logic.. The good part is that you know the type of input strconv.ParseFloat
expects.. So all you really have to do is take the user input and transform it to the programmatic standard http://floating-point-gui.de/formats/fp/. Given numbers are mostly universal, with the exception of commas and decimal points, there shouldn't be many use cases. You might even be able to generalize further and say there are two main formats.. https://www.quora.com/Why-do-some-countries-use-a-period-and-others-use-a-comma-to-separate-large-numbers, which is largely broken down to Europe et al and British/American, where German uses the standard almost all of Europe does. Under that assumption there isn't really much to do as the use cases comes down to 2.
package main
import (
"fmt"
"log"
"strconv"
"strings"
)
func normalizeGerman(old string) string {
s := strings.Replace(old, ",", ".", -1)
return strings.Replace(s, ".", "", 1)
}
func normalizeAmerican(old string) string {
return strings.Replace(old, ",", "", -1)
}
var locale map[string]func(string) string
func init() {
locale = make(map[string]func(string) string)
locale["DE-DE"] = normalizeGerman
locale["US"] = normalizeAmerican
}
func main() {
var f, f2 float64
var err error
// german
if val, ok := locale["DE-DE"]; ok {
f, err = strconv.ParseFloat(val("1.234,87"), 64)
if err != nil {
log.Fatal("german fail", err)
}
}
//american
if val, ok := locale["US"]; ok {
f2, err = strconv.ParseFloat(val("1,234.87"), 64)
if err != nil {
log.Fatal("american fail", err)
}
}
fmt.Println(f, f2)
}