2017-08-22 21 views
3

解析时间,我正在与一些数据来自多个来源的工作,这些来源之一是贤者ERP系统的格式HHMMSS00

我想在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] 
} 

有没有办法做到这一点,而无需通过上面去?也许本机与时间包?

回答

4

假设你正在从数据库中拉了回来2个独立的值,可以使用fmt.Sprintf0timeString。与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):格式字符串使用各种verbs被用于字符串替换。 %s专门用于呈现字符串或切片。其他流行动词包括%d(基数为10的整数)和%f(浮点数),其中包含文档中的完整列表。 %v动词是非常有用的,因为它会呈现参数的默认值,所以也可以在这里使用。
  • 0左边距填充:对于0左边填充参数,使用0后跟%后面的动词长度数字。这将在该长度编号中指定最大数量为0的参数。例如,%08s将呈现一个最多包含8个预置零的字符串。这意味着字符串""将为"00000000",而字符串"1234567"将导致""。如果字符串比长度长,则不会有前缀。

从文档:

%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 

更详细的,请在文档中:https://golang.org/pkg/fmt/

+0

这看起来像一个更好的解决方案。 'fmt.Sprintf(“%s%08s”,date,timeString)'''''''''''''''''''''''''''您介意再多加一点解释 - 我只是想更多地理解'%s%08s'。我假定'%s'输出日期,'%08s'输出时间,因为它是以前导零长度最多8个字符传入的。那是对的吗? – James

+2

这是正确的。我已经更新了答案,以包含更多的解释。如前所述,这在这里很有用,因为它会导致正确的时间长度,即使需要多个“0”。 '%s'和'%08s'都表示这些值是字符串,'%08s'表示预先添加了一个最多包含8个零的字符串。在这个特殊的例子中,'%v%08v''也可以使用,因为'%v'表示使用参数的默认值。 '%v'可以用于任何结构体,但是当你可以''s''的时候更加具体。 – Grokify

+0

感谢您的详细解释!很有用。我对Go很新,这非常有帮助。 – James