Go中灵活的日期/时间解析(在解析中添加默认值)

Tim*_*mGJ 7 datetime go

对于这个问题,我想解析命令行上传递给 Go 程序的日期/时间。目前,我使用该flag包填充字符串变量ts,然后使用以下代码:

if ts == "" {
    config.Until = time.Now()
} else {
    const layout = "2006-01-02T15:04:05"
    if config.Until, err = time.Parse(layout, ts); err != nil {
        log.Errorf("Could not parse %s as a time string: %s. Using current date/time instead.", ts, err.Error())
        config.Until = time.Now()
    }
}
Run Code Online (Sandbox Code Playgroud)

只要用户传递完全正确的格式(例如2019-05-20T09:07:33或类似的格式),这就可以正常工作。

然而,如果可能的话,我希望能够灵活地传递例如2019-05-20T09:07or2019-05-20T09或什至,并且2019-05-20在适当的情况下将小时、分钟和秒默认为 0。

有没有一种明智的方法可以做到这一点?


1本质上不需要我编写自己的解析器


更新

我已经找到了解决方案,虽然它不是特别优雅,但它似乎确实适用于我可能遇到的大多数情况。

package main

import (
    "fmt"
    "time"
)

func main() {

    const layout = "2006-01-02T15:04:05"
    var l string
    var input string

    for _, input = range []string{"2019-05-30", "2019-05-30T16", "2019-05-30T16:04", "2019-05-30T16:04:34",
                                "This won't work", "This is extravagantly long and won't work either"} {
        if len(input) < len(layout) {
            l = layout[:len(input)]
        } else {
            l = layout
        }
        if d, err := time.Parse(l, input); err != nil {
            fmt.Printf("Error %s\n", err.Error())
        } else {
            fmt.Printf("Layout %-20s gives time %v\n", l, d)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Fli*_*mzy 11

尝试每种格式,直到其中一种有效。如果都不起作用,则返回错误。

var formats = []string{"2006-01-02T15:04:05", "2006-01-02", ...}

func parseTime(input string) (time.Time, error) {
    for _, format := range formats {
        t, err := time.Parse(format, input)
        if err == nil {
            return t, nil
        }
    }
    return time.Time{}, errors.New("Unrecognized time format")
}
Run Code Online (Sandbox Code Playgroud)


zde*_*bra 6

我认为这个库就是您正在寻找的https://github.com/araddon/dateparse

在事先不知道格式的情况下解析许多日期字符串。使用扫描仪读取字节并使用状态机查找格式。

t, err := dateparse.ParseAny("3/1/2014")
Run Code Online (Sandbox Code Playgroud)


Foo*_*ooF 1

在您描述的特定场景中,您可以检查输入日期戳字符串的长度,并在其末尾添加适当长度的零内容以对应于您的layout. "T00:00:00"因此,基本上,您可以将与格式字符串相比长度缺失的尽可能多的字符串(从末尾开始计数)附加到输入中layout