gotimesage-erp

Parsing a time with the format HHMMSS00


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?


Solution

  • 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:

    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/