英文:
Parsing a time with the format HHMMSS00
问题
我正在处理来自多个来源的数据,其中一个来源是Sage ERP系统。
我试图特别引用Sage中的两个文件,一个是审计日期和审计时间(AUDTDATE
和AUDTTIME
)。
我需要解析这些数据并将其存储为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 ofverbs
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: To0
left pad an argument, use0
followed by a length number in the verb after the%
. This will prepended the argument with a maximum number of0
s 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/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论