2013-12-09 1 views
7

Golang에서 일반화하기위한 방법이 encoding/jsontime.Time 필드를 마샬링 할 때 다른 레이아웃을 사용합니까? 내가 원하는, 내가 어딘가 time.Format(layout)가 호출되고 상상,json.Marshal에서 사용하는 레이아웃을 재정 의하여 time.Time을 구성합니다.

s := {"starttime":time.Now(), "name":"ali"} 

나는 encdoding/jsonMarshal 기능을 사용하여 JSON으로 인코딩 할,하지만 난 내 사용자 지정 레이아웃을 사용하려면 : 기본적으로

나는이 구조체가 해당 레이아웃을 제어하려면

답변

10
지보의 대답에 의해 영감을 그 대답에 코멘트에서 해시으로

:

http://play.golang.org/p/pUCBUgrjZC

package main 

import "fmt" 
import "time" 
import "encoding/json" 

type jsonTime struct { 
    time.Time 
    f string 
} 

func (j jsonTime) format() string { 
    return j.Time.Format(j.f) 
} 

func (j jsonTime) MarshalText() ([]byte, error) { 
    return []byte(j.format()), nil 
} 

func (j jsonTime) MarshalJSON() ([]byte, error) { 
    return []byte(`"` + j.format() + `"`), nil 
} 

func main() { 
    jt := jsonTime{time.Now(), time.Kitchen} 
    if jt.Before(time.Now().AddDate(0, 0, 1)) { // 1 
     x := map[string]interface{}{ 
      "foo": jt, 
      "bar": "baz", 
     } 
     data, err := json.Marshal(x) 
     if err != nil { 
      panic(err) 
     } 
     fmt.Printf("%s", data) 
    } 
} 

이 솔루션 embeds jsonTime 구조체에로 time.time. Embedding은 모든 time.Time의 메소드를 jsonTime 구조체로 승격시켜 명시 적 유형 변환없이 사용할 수 있도록합니다 (// 1 참조). 로 time.time 임베드

또한 인코딩/JSON 마샬링 코드는 역방향 호환성을 이유로 MarshalText 방법 (MarshalText was added in Go 1.2, MarshalJSON 그 선행)보다 더 높은 우선 순위 MarshalJSON 방법을 촉진하는 단점이있다. 따라서 MarshalText에서 제공하는 사용자 지정 형식 대신 기본 time.Time 형식이 사용됩니다.

이 문제를 극복하기 위해 jsonTime 구조체에 대해 MarshalJSON을 재정의했습니다.

+0

시간 필드에서이 점을 "omitempty"라고 어떻게 생각하십니까? – nojo

6

어쩌면이게 뭔가 도움이 될까요? 여기도 가능합니다

package main 

import "fmt" 
import "time" 
import "encoding/json" 

type jsonTime struct { 
t time.Time 
f string 
} 

func (j jsonTime) MarshalText() ([]byte, error) { 
return []byte(j.t.Format(j.f)), nil 
} 

func main() { 
x := map[string]interface{}{ 
    "foo": jsonTime{t: time.Now(), f: time.Kitchen}, 
    "bar": "baz", 
} 
data, err := json.Marshal(x) 
if err != nil { 
    panic(err) 
} 
fmt.Printf("%s", data) 
} 

:

http://play.golang.org/p/D1kq5KrXQZ 그냥 MarshalText에게 당신이 그것을 표시 할 방법을 구현하는 사용자 정의 유형을 확인하십시오.

+0

감사합니다. 앞으로 나아갈 것입니다. 그러나 모든 시간을 변환 할 필요가 없기를 바랍니다. 시간을'mytime '으로 바꿀 때마다, 시간을 사용하고 싶을 때마다 되돌아 가십시오. – Ali

+1

사용자 정의 유형에 대해 time.Time 메소드를 호출하려면 이름을 지정하는 대신 time.Time을 임베드하십시오. 예 : http://play.golang.org/p/Vudw0hhnwe – ChrisH

+0

많은 실수가 아니라면'time.Time'을 삽입하면 json 인코딩에'MarshalText'가 작동하지 않습니다. 이것은 처음부터. 이름을 지어야합니다. – Ali

3

먼저, 기본 RFC3339 이외의 시간 형식을 사용하지 않는 것이 좋습니다. 좋은 시간 형식이고 여러 언어로 파싱 할 수 있으므로 다른 사람의 API가 필요하기 때문에 다른 형식이 필요하지 않으면 기본값을 사용하는 것이 가장 좋습니다. http://play.golang.org/p/DKaTbV2Zvl

:

는하지만, 그래서 여기에 원수/비 정렬 화 단계 작업의 대부분을 이동 하나 개의 솔루션이며, 이상적인 구조를 잎, 다른 사람의 API를 소모에서이 문제를 해결 했어

+0

RFC3339는 다른 어떤 제품보다 어떻게 더 좋습니까? (예 : RFC822Z) – themihai

관련 문제