解析具有格式HHMMSS00的时间

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

Parsing a time with the format HHMMSS00

问题

我正在处理来自多个来源的数据,其中一个来源是Sage ERP系统。

我试图特别引用Sage中的两个文件,一个是审计日期和审计时间(AUDTDATEAUDTTIME)。

我需要解析这些数据并将其存储为Microsoft SQL Server数据库中的DATETIME类型。

目前,我只是试图找出最佳的解析方法。

下面是数据可能的示例:

+----------+----------+
| AUDTDATE | AUDTTIME |
+----------+----------+
| 20170228 |  5013756 |
+----------+----------+

AUDTDATE是yyyymmdd格式,AUDTTIME是HHMMSS00格式。

所以我尝试了下面的代码作为测试:

func main() {
    value := "20170228 5013756"
    layout := "20060102 15040500"

    t, _ := time.Parse(layout, value)
    fmt.Println(t)
}

运行时,它并不起作用,只返回0001-01-01 00:00:00 +0000 UTC

如果我将时间更改为050137,将布局更改为150405,那么它就可以正常工作:

func main() {
    value := "20170228 050137"
    layout := "20060102 150405"

    t, _ := time.Parse(layout, value)
    fmt.Println(t)
}

我能想到的一种处理方法是去掉末尾的毫秒,并检查长度,如果需要,在开头添加一个零。

这似乎是一个相当丑陋的解决方案,涉及到类似下面的操作:

func main() {
    date := "20170228"
    timeString := "5013756"
    value := date + prepareTime(timeString)
    layout := "20060102150405"

    t, _ := time.Parse(layout, value)
    fmt.Println(t)
}

func prepareTime(time string) string {
    if len(time) == 7 {
        time = "0" + time
    }
    return time[:6]
}

有没有一种方法可以不经过上述步骤来实现?也许可以直接使用time包来处理?

英文:

I'm working with some data from multiple sources and one of these sources is a Sage ERP system.

I am trying to reference two files in Sage in particular, an audit date and audit time (AUDTDATE and AUDTTIME).

I need to parse this and store it as a DATETIME in a Microsoft SQL Server database.

Currently, I am just trying to figure out the best way to parse this.

An example of what the data might look like is below:

+----------+----------+
| AUDTDATE | AUDTTIME |
+----------+----------+
| 20170228 |  5013756 |
+----------+----------+

AUDTDATE is a yyyymmdd format and the AUDTTIME is HHMMSS00.

So I tried the below as a test:

func main() {
	value := "20170228 5013756"
	layout := "20060102 15040500"

	t, _ := time.Parse(layout, value)
	fmt.Println(t)
}

This doesn't work, it just returns 0001-01-01 00:00:00 +0000 UTC when run.

If I change the time to this 050137 and the layout to 150405 then this works fine:

func main() {
	value := "20170228 050137"
	layout := "20060102 150405"

	t, _ := time.Parse(layout, value)
	fmt.Println(t)
}

One way that I can think of to deal with this is to strip the milliseconds off from the end and then check the length and add a zero to the beginning if it needs one.

This seems like a pretty ugly solution and would involve doing something like this:

func main() {
	date := "20170228"
	timeString := "5013756"
	value := date + prepareTime(timeString)
	layout := "20060102150405"

	t, _ := time.Parse(layout, value)
	fmt.Println(t)
}

func prepareTime(time string) string {
	if len(time) == 7 {
		time = "0" + time
	}
	return time[:6]
}

Is there a way to do this without going through the above? Perhaps natively with the time package?

答案1

得分: 4

假设你从数据库中获取了两个不同的值,你可以使用fmt.Sprintf函数来对timeString进行零填充。将其与date字符串组合起来,可以使用以下代码:

value := fmt.Sprintf("%s %08s", date, timeString)[:15]

在你的代码中:

func main() {
    date := "20170228"
    timeString := "5013756"
    value := fmt.Sprintf("%s %08s", date, timeString)[:15]
    layout := "20060102 150405"

    t, _ := time.Parse(layout, value)
    fmt.Println(t)
}

结果为:

2017-02-28 05:01:37 +0000 UTC

这种方法很有用,因为它还可以正确地填充任何较短的时间值,例如13756将被转换为00013756

fmt.Sprintf函数用于使用指定的格式字符串和参数列表(...interface{})将参数格式化为字符串。格式字符串告诉函数如何渲染参数。

这个格式字符串使用了两个注意事项:

  • 字符串占位符(%s):格式字符串使用各种占位符来进行字符串替换。%s用于渲染字符串或切片。其他常用的占位符包括%d用于十进制整数和%f用于浮点数,完整的列表可以在文档中找到。%v占位符也非常有用,可以用于渲染参数的默认值。
  • 0左填充:要对参数进行0左填充,可以在占位符后面使用0和长度数字。这将在参数前面添加指定长度的0。例如,%08s将渲染一个最多带有8个前导零的字符串。这意味着一个空字符串""将变为"00000000",而字符串"1234567"将变为"01234567"。如果字符串长度超过指定长度,将不会添加任何前导零。

根据文档:

%s	字符串或切片的未解释字节

0   使用前导零而不是空格进行填充;
    对于数字,这将在符号之后移动填充

更详细的信息可以在文档中找到:https://golang.org/pkg/fmt/

英文:

Assuming that you're pulling back 2 separate values from the DB, you can use fmt.Sprintf to 0 pad timeString. Combining it with the date string, you can use the following:

value := fmt.Sprintf("%s %08s", date, timeString)[:15]

In your code:

func main() {
    date := "20170228"
    timeString := "5013756"
    value := fmt.Sprintf("%s %08s", date, timeString)[:15]
    layout := "20060102 150405"

    t, _ := time.Parse(layout, value)
    fmt.Println(t)
}

Results:

2017-02-28 05:01:37 +0000 UTC

This approach is useful because it will also correctly pad any shorter value of time, e.g. 13756 will be converted to 00013756.

The fmt.Sprintf function is useful to format arguments into a string using the formatting you desire as specified by a format string and a list of arguments (...interface{}). The format string tells the function how to render the arguments.

This format string uses two items of note:

  • String verb (%s): The format string uses a variety of verbs that are used for string substitutions. %s is specifically to render a string or a slice. Other popular verbs include %d for base 10 integer and %f for float with a complete list in the docs. The %v verb is very useful can also be used here as it will render an argument's default value.
  • 0 left padding: To 0 left pad an argument, use 0 followed by a length number in the verb after the %. This will prepended the argument with a maximum number of 0s specified in the length number. For example, %08s will render a string with up to 8 prepended zeros. This means a string "" will be "00000000" while a string "1234567" will result in "01234567". If the string is longer than the length, nothing will be prepended.

From the documentation:

%s	the uninterpreted bytes of the string or slice

0   pad with leading zeros rather than spaces;
    for numbers, this moves the padding after the sign

More detailed is available in the documentation: https://golang.org/pkg/fmt/

huangapple
  • 本文由 发表于 2017年8月22日 12:20:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/45808852.html
匿名

发表评论

匿名网友

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

确定