如何在Go语言中从非英语字符串中解析月份

huangapple go评论74阅读模式
英文:

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

问题

我想在Go中将以下字符串解析为日期:

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

我按照这个尝试了一下,得到了以下代码:

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
}

这段代码对于英文字符串非常有效。

我的问题:我想解析德语字符串。例如:

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

我知道,我可以通过正则表达式匹配日、月和年,然后进行解析。但是,有没有办法告诉time.Parse使用不同的月份常量集?

英文:

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?

答案1

得分: 8

目前时间包(time package)还没有国际化支持。在等待这个功能实现之前,你可以尝试使用一个包装器(wrapper package),比如:

github.com/goodsign/monday

根据 monday 的文档所述:

Monday 不是标准时间包的替代品。它是在国际化功能准备好之前使用的临时解决方案。

这就是为什么 monday 不会创建任何额外的解析算法、布局标识符。它只是 time.Format 和 time.ParseInLocation 的一个包装器,并使用相同的布局标识符、常量等。

以下是使用 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)
}

输出结果:

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

英文:

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

答案2

得分: 0

如您从time包的format.go源代码中可以看到,星期和月份的名称被定义为变量 - (long|short)(Day|Month)Names。不幸的是,这些名称是小写的,这意味着它们没有被导出。如果它们被导出了,您可以在调用time.Parse()之前修改它们。也许您应该提交一个bug报告,将这些变量设为公开,或者提供一种修改它们的方法,或者自己修改并提交一个补丁。当然,您也可以创建一个私有的time包副本,在那里进行所需的更改。

编辑: ANisus建议的包装器包以比我的建议更实用的方式解决了这个问题。不过,我的回答展示了您如何利用Go是开源的特性来自己研究标准库中可能存在的问题的解决方案。

英文:

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

得分: 0

你可以使用任何月份的名称,例如2006年1月2日,它会为你翻译成正确的日期。

英文:

You can just use any name for the month, such as Januar 2, 2006 and it will return the correct date translated for you.

huangapple
  • 本文由 发表于 2014年2月11日 16:30:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/21696689.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定