一尘不染

从字符串获取整数月份值

go

我正在从AWS解析一个cron字符串,看起来像这样cron(0 7 13 November ? 2019)。有没有一种干净的方法可以November追溯到11使用Go的内置类型?该time.Month类型允许映射intstring,但似乎没有办法进行相反的操作。我想念什么吗?现在,我已经写了这个得到map[string]int我使用这样的:monthi := getMonths()[monthName]

func getMonths() map[string]int {
    m := make(map[string]int)
    for i := 1; i < 13; i++ {
        month := time.Month(i).String()
        m[month] = i
    }
    return m
}

阅读 228

收藏
2020-07-02

共1个答案

一尘不染

前言:
我在中发布了此实用程序github.com/icza/gox,请参见timex.ParseMonth()


这是目前最好的方法。

最好的方法是使用包级变量,并且仅填充一次地图。

通过这种方式进行人口调查更加干净和安全:

var months = map[string]time.Month{}

func init() {
    for i := time.January; i <= time.December; i++ {
        months[i.String()] = i
    }
}

测试它:

for _, s := range []string{"January", "December", "invalid"} {
    m := months[s]
    fmt.Println(int(m), m)
}

输出(在Go Playground上尝试):

1 January
12 December
0 %!Month(0)

请注意,此映射具有灵活性,您可以添加短月份名称,以映射到同一月份。例如,您也可以添加months["Jan"] = time.January,因此,如果您的输入是"Jan",您也可以获取time.January。可以通过在同一循环中对长名称进行切片来轻松完成此操作,例如:

for i := time.January; i <= time.December; i++ {
    name := i.String()
    months[name] = i
    months[name[:3]] = i
}

另请注意,可以time.Parse()在布局字符串为的地方进行解析"January"

for _, s := range []string{"January", "December", "invalid"} {
    t, err := time.Parse("January", s)
    m := t.Month()
    fmt.Println(int(m), m, err)
}

哪些输出(在Go Playground上尝试):

1 January <nil>
12 December <nil>
1 January parsing time "invalid" as "January": cannot parse "invalid" as "January"

但是,简单的地图查找在性能上胜于此。

2020-07-02