Golang - 自定义时间。时间类型返回数据存储区

时间:2016-04-12 04:49:07

标签: json go unmarshalling google-cloud-datastore

我一直在处理从JSON POST到我们的Golang API的各种自定义时间格式示例。我已经获得了UnmarshalJSON的覆盖功能,看起来一切正常。但是,当我将结构保存到数据存储区时,它不被识别为time.Time值因此未被设置/保存。 ' toString'函数正在打印出我希望在数据存储中看到的正确时间,但无法弄清楚如何转换它或将其转换为时间。数据存储上的时间保存。这是我们正在构建的简单日志记录API功能。见下面的代码。

我想像UnmarshalJSON将任意字符串转换为time.Time然后转换为' Timestamp' (在这种情况下)是否存在一个数据存储等价物,用于将其恢复到时间。保存之前的时间?

感谢您提供任何帮助/指导。我确实有这样一个' DateString'是在解组“AppLog”时通过JSON设置的字符串值。然后我将其转换为' Date' time.Time,但是想要更多一点光滑的'如果可能的话,使用UnmarshalJSON。

package logger

import (
    "encoding/json"
    "errors"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "time"

    "golang.org/x/net/context"

    "google.golang.org/appengine"
    "google.golang.org/appengine/datastore"

    "github.com/gorilla/mux"
)

func init() {
    router := mux.NewRouter()

    router.HandleFunc("/applogger", DoLog).Methods("POST")

    http.Handle("/applogger/", router)
}

// DoLog --
func DoLog(rw http.ResponseWriter, request *http.Request) {
    var applog AppLog

    body, err := ioutil.ReadAll(io.LimitReader(request.Body, 1048576))

    if err != nil {
        panic(err)
    }

    if err := request.Body.Close(); err != nil {
        panic(err)
    }

    if err := json.Unmarshal(body, &applog); err != nil {
        panic(err)
    }

    applog.IP = request.RemoteAddr

    log.Print("my timestamp", applog.Date)

    ctx := appengine.NewContext(request)
    applog.Save(ctx)

    fmt.Fprint(rw, "applogger - success")
}

// AppLog struct
type AppLog struct {
    Application string    `json:"application" datastore:"application"`
    Platform    string    `json:"platform" datastore:"platform,noindex"`
    Date        Timestamp `json:"date" datastore:"date"`
    Data        string    `json:"data" datastore:"data,noindex"`
    IP          string    `json:"-" datastore:"ip,noindex"`
}

// Save --
func (al *AppLog) Save(ctx context.Context) *datastore.Key {

    key := datastore.NewKey(ctx, "AppLog", "", 0, nil)

    if _, err := datastore.Put(ctx, key, al); err != nil {
        return nil
    }

    return key
}

// Timestamp -- Generic Timestamp entity to handle different generic date formats
type Timestamp time.Time

const TimestampDateLayout1 = "2006-01-02 15:04:05 +0000"

func (t *Timestamp) UnmarshalJSON(b []byte) error {
    ts, err := time.Parse(TimestampDateLayout1, string(b[1:len(b)-1]))
    if err == nil {
        log.Print("ts ", ts)
        *t = Timestamp(ts)
        log.Print("t ", t)
        return nil
    }

    *t = Timestamp(time.Now())
    return nil
}

func (t Timestamp) String() string {
    return time.Time(t).String()
}

2 个答案:

答案 0 :(得分:0)

time.Time已经有UnmarshalJSON method。它将从RFC3339格式化为time.Time的JSON字符串解组。

如果您之后需要使用其他字符串格式,则可以使用

(t *time.Time).Format(layout string)

具有所需的任何格式。

答案 1 :(得分:0)

如果有很多结构,你只是实现自定义编组和解组函数,那么这样做有很多工作要做。您可以改用另一个lib,例如json-iterator扩展名jsontime

import "github.com/liamylian/jsontime"

var json = jsontime.ConfigWithCustomTimeFormat

type Book struct {
    Id        int           `json:"id"`
    UpdatedAt *time.Time    `json:"updated_at" time_format:"sql_date" time_utc:"true"`
    CreatedAt time.Time     `json:"created_at" time_format:"sql_datetime" time_location:"UTC"`
}