将json格式的时间戳转换为golangs time.Time

时间:2019-03-11 21:02:17

标签: string go time

我在json中有一个日期时间字符串,格式如下:

 /Date(315513000000+0530)/ 

我想将其转换为golangs time.Time格式。我尝试将此字符串传递给以下函数

func parseDateField(dateInput string) (int64, error) {
    startIdx := strings.Index(dateInput, "(")
    if startIdx == -1 {
        return 0, errors.New("Error parsing quote Date. '(' symbol not found")
    }

    endIdx := strings.Index(dateInput, "+")
    if endIdx == -1 {
    return 0, errors.New("Error parsing quote Date. '+' symbol not found")
     }
    dateStr := dateInput[startIdx+1 : endIdx]
    date, err := strconv.ParseInt(dateStr, 10, 64)
    if err != nil {
        fmt.Printf(" err : \n %+v \n", err)
        return 0, err
     }
     tm := time.Unix(date, 0)
     fmt.Printf("\n time  : \n %+v \n", tm)
     dateAsEpoch := int64(date / 1000)
     fmt.Printf("\n dateAsEpoch  : \n %+v \n", dateAsEpoch)
     return dateAsEpoch, nil
}

我得到以下输出

 time  : 
 11968-03-18 01:30:00 +0530 IST 


 dateAsEpoch  : 
 315513000 

我猜解析不正确-我在做什么错了?

1 个答案:

答案 0 :(得分:3)

该时间格式似乎是从纪元起经过的毫秒数和带符号的4位区域偏移(小时和分钟)。

最简单的方法是使用fmt.Sscanf()进行解析,如下所示:

_, err = fmt.Sscanf(s, "/Date(%d+%02d%02d)/", &ms, &zoneHour, &zoneMin)

当然,如果区域偏移为负,则格式将不匹配。可以通过第二次尝试解析来解决,将+替换为格式字符串中的-

一旦有了ms,将其乘以一百万即可得到纳秒,因此可以将其传递给time.Unix()(在[0, 999999999]之外传递纳秒的值是有效的范围)。

最后,您可以使用time.FixedZone()获取与输入中的区域偏移相对应的区域,然后使用Time.In()来“切换”到该区域。

请注意,自历元以来的毫秒数与区域无关(在UTC区域中给出)。仅需要切换到源的区域偏移,以便在打印时间(或访问其“字段”(如年,月,日))时,您将看到预期的日期和时间,因为在另一个区域中会有所不同。例如,您拥有的实例指定日期1980-01-01和一天中的0时间。如果没有+0530区域,那将是另一天,那就是1979-12-31 18:30:00 +0000 UTC

下面是一个示例:

func parse(s string) (t time.Time, err error) {
    var ms int64
    var zhour, zmin int

    if _, err = fmt.Sscanf(s, "/Date(%d+%02d%02d)/", &ms, &zhour, &zmin); err != nil {
        if _, err = fmt.Sscanf(s, "/Date(%d-%02d%02d)/", &ms, &zhour, &zmin); err != nil {
            return time.Time{}, fmt.Errorf("Failed to parse: %v", err)
        }
        zhour = -zhour
        zmin = -zmin
    }

    t = time.Unix(0, ms*1000000)
    t = t.In(time.FixedZone("", zhour*3600+zmin*60))
    return
}

测试:

fmt.Println(parse("/Date(315513000000+0530)/"))
fmt.Println(parse("/Date(315513000000-0530)/"))
fmt.Println(parse("invalid"))

输出(在Go Playground上尝试):

1980-01-01 00:00:00 +0530 +0530 <nil>
1979-12-31 13:00:00 -0530 -0530 <nil>
0001-01-01 00:00:00 +0000 UTC Failed to parse: input does not match format