Elegant implementation of Go json time format

Keywords: Programming JSON encoding Mac Python

At the beginning, the requirement is very simple. You only need to deserialize the time string in json according to the specified format https://www.jianshu.com/p/c02af04165e2 , the code is as follows:

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

// set time format
const (
    timeFormat = "2006-01-02 15:04:05"
)

// Custom type
type JsonDate time.Time

// JsonDate deserialization
func (t *JsonDate) UnmarshalJSON(data []byte) (err error) {
    newTime, err := time.ParseInLocation("\""+timeFormat+"\"", string(data), time.Local)
    *t = JsonDate(newTime)
    return
}

// JsonDate serialization
func (t JsonDate) MarshalJSON() ([]byte, error) {
    timeStr := fmt.Sprintf("\"%s\"", time.Time(t).Format(timeFormat))
    return []byte(timeStr),nil
}

// string method
func (t JsonDate) String() string {
    return time.Time(t).Format(timeFormat)
}

// Define User structure
type User struct {
    UserName      string    `json:"user_name"`
    Sex           bool      `json:"sex"`
    BirthDay      time.Time `json:"birth_day"`
    Age           int       `json:"age"`
    Score         float64   `json:"score"`
    StartWorkDate JsonDate  `json:"start_work_date"`
}

func main() {
    // Turn json
    Serial()
    // json to struct
    UnSerial()
}

// Serialization to Json
func Serial() {

    user := User{
        UserName:      "Mac",
        Sex:           false,
        BirthDay:      time.Now(),
        Age:           18,
        Score:         95.8,
        StartWorkDate: JsonDate(time.Now()),
    }

    jsonByte, err := json.Marshal(user)

    if err != nil {
        fmt.Println("json serial err: ", err.Error())
    }
    fmt.Println(string(jsonByte))
}

// Anti serialization into objects
func UnSerial() {
    str := `{"user_name":"Mac","sex":false,"birth_day":"2020-02-28T18:13:59.738342443+08:00","age":18,"score":95.8,"start_work_date":"2020-02-28 18:13:59"}`
    user := new(User)
    err := json.Unmarshal([]byte(str), user)

    if err != nil {
        fmt.Println("json unSerial err: ",err.Error())
    }

    fmt.Printf("%+v\n",user)
}

However, as the demand increases later, it is necessary to copy and modify the methods in the time package, such as obtaining the time stamp / year / month / day / hour / minute / second, etc., so this method is not desirable

I use the following methods. I only need to rewrite the methods I need. Other methods don't need to be copied and modified, and the implementation is simpler:

package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"
)

const timeFormatYMDhms = "2006-01-02 15:04:05" // Time format used by json
type JSONDATE struct {
	time.Time // Time types used by json
}

// JSONDATE deserialization
func (self *JSONDATE) UnmarshalJSON(data []byte) (err error) {
	newTime, _ := time.ParseInLocation("\""+timeFormatYMDhms+"\"", string(data), time.Local)
	*&self.Time = newTime
	return
}

// JSONDATE serialization
func (self JSONDATE) MarshalJSON() ([]byte, error) {
	timeStr := fmt.Sprintf("\"%s\"", self.Format(timeFormatYMDhms))
	return []byte(timeStr), nil
}

//Output string
func (self JSONDATE) String() string {
	return self.Time.Format(timeFormatYMDhms)
}

self should not be used by golang standards, but python is the best language

Posted by colossus_09 on Fri, 17 Apr 2020 07:38:58 -0700