我一直在处理从JSON POST到我们的Go API的各种自定义时间格式的示例。我有一个UnmarshalJSON的重写函数,看起来一切正常。但是,当我将结构保存到数据存储区时,它没有被识别为time.Time值,因此未设置/保存。 'toString'函数可以打印出我想在数据存储区中看到的正确时间,但无法弄清楚如何将其转换或将其转换为时间。这是我们正在构建的简单的日志记录API功能。请参见下面的代码。
我想像UnmarshalJSON将任意字符串转换为time.Time,然后转换为'Timestamp'(在这种情况下,是否有一个等效的数据存储区,可以将其恢复为time.Time,然后保存?
谢谢您的帮助/指导。我确实有这样一个想法,即“ 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()
}
time.Time已经有一个UnmarshalJSON method。它将从RFC3339格式化为time.Time的JSON字符串中解组。
如果此后需要其他字符串格式,则可以使用
(t *time.Time).Format(layout string)
具有所需的任何格式。
如果有很多结构,而您只是实现自定义编组和解编功能,那么要做很多工作。您可以改用另一个库,例如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"`
}