How to parse month in go from non-english String w

2019-06-27 09:35发布

I want to parse the following string to a date in go:

"This item will be released on March 9, 2014."

I followed this and came up whith:

func findReleaseDateString(raw string) time.Time {
  test, err := time.Parse("This item will be released on January 2, 2006.", raw)
  if err != nil {
      panic(err)
  }

 return test
}

Which works like a charm for english strings.

My problem: I would like to parse german strings. Like:

"Dieser Artikel wird am 9. März 2014 erscheinen."

I am aware, that I could match day, month and year via a regex and then parse it. But is there any possibility to tell time.Parse to use a different set of constants for month?

标签: time go
2条回答
We Are One
2楼-- · 2019-06-27 10:13

As you can see from the sourcecode of format.go from package time, the names of days/months are defined as variables - (long|short)(Day|Month)Names. Unfortunately, the names are lowercase, which means they are not exported. If they were, you could modify them before calling time.Parse(). Maybe you should file a bug to make these variables public or provide a way to modify them, or do it yourself and submit a patch. You can also, of course, create a private copy of the time package and make the needed changes there.

Edit: the wrapper package suggested by ANisus solves the problem in a more pragmatic way than my suggestions. Still, my answer shows how you can use the fact that Go is open source to investigate possible solutions to issues in the standard library yourself.

查看更多
干净又极端
3楼-- · 2019-06-27 10:22

There is currently no i18n support for the time package. While waiting for that to happen, you can try using a wrapper package such as:

github.com/goodsign/monday

As stated by monday's documentation:

Monday is not an alternative to standard time package. It is a temporary solution to use while the internationalization features are not ready.

That's why monday doesn't create any additional parsing algorithms, layout identifiers. It is just a wrapper for time.Format and time.ParseInLocation and uses all the same layout IDs, constants, etc.

Here is your example using monday:

package main

import (
    "fmt"
    "github.com/goodsign/monday"
    "time"
)

func findReleaseDateString(raw string) time.Time {
    loc, _ := time.LoadLocation("Europe/Berlin")
    t, err := monday.ParseInLocation("Dieser Artikel wird am 2. January 2006 erscheinen.", raw, loc, monday.LocaleDeDE)
    if err != nil {
        panic(err)
    }

    return t
}

func main() {
    t := findReleaseDateString("Dieser Artikel wird am 9. März 2014 erscheinen.")
    fmt.Println(t)
}

Output:

2014-03-09 00:00:00 +0100 CET

查看更多
登录 后发表回答