diff --git a/xtime/time.go b/xtime/time.go index 43974fc..e27ba63 100644 --- a/xtime/time.go +++ b/xtime/time.go @@ -18,6 +18,7 @@ package xtime import ( + "encoding/json" "fmt" "time" @@ -92,6 +93,11 @@ func (d *Duration) UnmarshalJSON(bs []byte) error { return nil } +// MarshalJSON implements json.Marshaler - Converts duration to human-readable format (e.g., "2h", "30m") +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(time.Duration(d).String()) +} + // MarshalMsg appends the marshaled form of the object to the provided // byte slice, returning the extended slice and any errors encountered. func (d Duration) MarshalMsg(bytes []byte) ([]byte, error) { diff --git a/xtime/time_unmarshal_test.go b/xtime/time_unmarshal_test.go index 26ae22c..8062d5d 100644 --- a/xtime/time_unmarshal_test.go +++ b/xtime/time_unmarshal_test.go @@ -141,4 +141,22 @@ durationPointer: 168h0m1s if string(yamlData) != expected { t.Errorf("Expected:\n%s\nGot:\n%s", expected, string(yamlData)) } + + jsonData, err := json.Marshal(&testData) + if err != nil { + t.Fatalf("Failed to marshal JSON: %v", err) + } + expectedJSON := `{"a":"1s","dur":"0s","durationPointer":"168h0m1s"}` + if string(jsonData) != expectedJSON { + t.Errorf("Expected:\n%s\nGot:\n%s", expectedJSON, string(jsonData)) + } + + // The marshaled JSON must be readable back by UnmarshalJSON. + var back testDuration + if err := json.Unmarshal(jsonData, &back); err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + if back.A != d1 || back.Dur != d2 || back.DurationPointer == nil || *back.DurationPointer != d3 { + t.Errorf("JSON round-trip mismatch: got %+v", back) + } }