2016-04-12 7 views
1

私はGolang APIのJSON POSTに由来するカスタムタイムフォーマットのさまざまな例を扱っています。私はUnmarshalJSONのオーバーライドされた機能をすべて一見うまく動作しています。しかし、構造体をデータストアに保存しようとすると、time.Time値が設定/保存されないため、認識されません。 'toString'関数は、データストアに表示したい正しい時刻を出力していますが、データストアを変換する方法や時間をキャストする方法を理解することはできません。これは簡単なロギングAPI機能です。以下のコードを参照してください。Golang - カスタムtime.Timeタイプをデータストアに戻す

任意の文字列をtime.Timeから 'Timestamp'(この場合)に変換するUnmarshalJSONのようなものがあります。

ご協力いただきありがとうございます。私は、 'DateString'がJSONを介して設定された文字列値であるように 'AppLog'をアンマーシャリングしてから '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() 
} 

答えて

0

時間。時刻はすでにUnmarshalJSON methodです。これは、RFC3339の形式のJSON文字列から時刻をタイムマットします。

あなたはその後別の文字列形式でそれを必要とする場合は、あなただけの書式設定どんな希望で

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

を使用することができます。

+0

Matt、ありがとう、私はその時を知っています。タイムにはアンマーシャルソン法があります。問題はさまざまな入力タイプを扱うことです。それは私がRFC3339形式でsnotの日付/時刻文字列を受け取ることがありますので、time.Timeに解析する必要があります。それが私がここでやっていることです。しかし、私はそれをタイムスタンプからタイムアウトに戻す必要があります。データストアに入る時間。上記の例では、来るJSONの日付は2016-03-31 16:49:48 +0000です。これはエラーです:panic:解析時間 "" 2016-03-31 16:49:48 +0000 "" as "" 2006-01-02T15:04:05Z07:00 "": "T"として16:49:48 +0000 ""を解析できません – djneely

関連する問題