原创

go中的时间序列化/反序列化的问题

温馨提示:
本文最后更新于 2020年08月30日,已超过 1,545 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

标准时间模板:2006-01-02 15:04:05

这应该是go出生的日期。

假如我要反序列化的话:

var a models.Identification
if err = json.Unmarshal(body, &a); err != nil {
    log.Printf("Unmarshal err, %v\n", err)
    return
}

我的model是这样子设计的:

type Identification struct {
    IdDocumentType   *IdDocumentType  `json:"idDocumentType" validate:"required"`
    IdDocumentNumber string           `json:"idDocumentNumber" validate:"required"`
    IssueDate        time.Time        `json:"issueDate" validate:"required,datetime"`
    ExpiryDate       time.Time        `json:"expiryDate" validate:"required,datetime"`
    IssuingAuthority string           `json:"issuingAuthority" validate:"required"`
}

此时会报错,无法反序列化这个时间。

Unmarshal IssueDate、ExpiryDate

报错归根类似于:...as ""2006-01-02T15:04:05Z07:00"": cannot parse """ as "T"

这是因为反序列化的时候,会使用2006-01-02 15:04:05去反序列化,我传入的时间是2015-03-28这种格式,所以会转换出错。

解决办法:

使用时间模板,时间

// time format template(UnmarshalJSON and MarshalJSON)
const (
    YYYYMMDD          = "2006-01-02"
    DefaultTimeFormat = "2006-01-02 15:04:05"
)

// JSONTime is time
type JSONTime time.Time

// UnmarshalJSON for JSON Time
func (t *JSONTime) UnmarshalJSON(data []byte) (err error) {
    now, err := time.ParseInLocation(`"`+YYYYMMDD+`"`, string(data), time.Local)
    *t = JSONTime(now)
    return
}

// MarshalJSON for JSON Time
func (t JSONTime) MarshalJSON() ([]byte, error) {
    b := make([]byte, 0, len(YYYYMMDD)+2)
    b = append(b, '"')
    b = time.Time(t).AppendFormat(b, YYYYMMDD)
    b = append(b, '"')
    return b, nil
}

// String for JSON Time
func (t JSONTime) String() string {
    return time.Time(t).Format(YYYYMMDD)
}

model要改一下:

// Identification structure of the Customer RequestBody struct
type Identification struct {
    IDDocumentType   IDDocumentType `json:"idDocumentType" validate:"required"`
    IDDocumentNumber string         `json:"idDocumentNumber" validate:"required"`
    IssueDate        JSONTime       `json:"issueDate" validate:"required,datetime"`
    ExpiryDate       JSONTime       `json:"expiryDate" validate:"required,datetime"`
    IssuingAuthority string         `json:"issuingAuthority" validate:"required"`
}

使用Test:

package models

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestJSONTime_UnmarshalJSON(t *testing.T) {

    var timeUnmarshalJSON JSONTime
    err := timeUnmarshalJSON.UnmarshalJSON([]byte(`"1970-01-26"`))

    assert.Nil(t, err)
}

func TestJSONTime_MarshalJSON(t *testing.T) {
    var timeUnmarshalJSON JSONTime
    marshalJSON, err := timeUnmarshalJSON.MarshalJSON()

    assert.Nil(t, err)
    assert.NotNil(t, marshalJSON)
}

func TestJSONTime_String(t *testing.T) {
    var timeUnmarshalJSON JSONTime
    s := timeUnmarshalJSON.String()

    assert.NotNil(t, s)
}
本文目录