为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
凤凰求蛊 2023-06-12 17:15:09
我在 json 中有一个日期时间字符串,格式如下 /Date(315513000000+0530)/ 我想将其转换为 golangstime.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 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

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

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

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

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

一旦你有了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


查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信