@@ -11,6 +11,7 @@ import (
1111 "sort"
1212 "strconv"
1313 "strings"
14+ "time"
1415)
1516
1617var (
@@ -40,6 +41,13 @@ type Options struct {
4041 // when it's safe. This is useful for diffing two structures, where pointer variables would cause
4142 // false changes. However, circular graphs are still detected and elided to avoid infinite output.
4243 DisablePointerReplacement bool
44+
45+ // FormatTime, if true, will format [time.Time] values using the TimeFormat string.
46+ FormatTime bool
47+
48+ // TimeFormat is the format string used to format [time.Time] values. If blank,
49+ // time.Time.String() is used.
50+ TimeFormat string
4351}
4452
4553// Config is the default config used when calling Dump
@@ -59,6 +67,7 @@ type dumpState struct {
5967 parentPointers ptrmap
6068 currentPointer * ptrinfo
6169 homePackageRegexp * regexp.Regexp
70+ timeFormatter func (t time.Time ) string
6271}
6372
6473func (s * dumpState ) write (b []byte ) {
@@ -129,6 +138,14 @@ func (s *dumpState) dumpSlice(v reflect.Value) {
129138}
130139
131140func (s * dumpState ) dumpStruct (v reflect.Value ) {
141+ val := v .Interface ()
142+ if t , ok := val .(time.Time ); ok && s .timeFormatter != nil {
143+ s .writeString ("time.Time{ /* " )
144+ s .writeString (s .timeFormatter (t ))
145+ s .writeString (" */ }" )
146+ return
147+ }
148+
132149 dumpPreamble := func () {
133150 s .dumpType (v )
134151 s .write ([]byte ("{" ))
@@ -246,7 +263,6 @@ func (s *dumpState) dumpChan(v reflect.Value) {
246263}
247264
248265func (s * dumpState ) dumpCustom (v reflect.Value , buf * bytes.Buffer ) {
249-
250266 // Dump the type
251267 s .dumpType (v )
252268
@@ -293,6 +309,8 @@ func (s *dumpState) dump(value interface{}) {
293309 s .dumpVal (v )
294310}
295311
312+ var dumperType = reflect .TypeOf ((* Dumper )(nil )).Elem ()
313+
296314func (s * dumpState ) descendIntoPossiblePointer (value reflect.Value , f func ()) {
297315 canonicalize := true
298316 if isPointerValue (value ) {
@@ -345,7 +363,6 @@ func (s *dumpState) dumpVal(value reflect.Value) {
345363 }
346364
347365 // Handle custom dumpers
348- dumperType := reflect .TypeOf ((* Dumper )(nil )).Elem ()
349366 if v .Type ().Implements (dumperType ) {
350367 s .descendIntoPossiblePointer (v , func () {
351368 // Run the custom dumper buffering the output
@@ -464,6 +481,18 @@ func newDumpState(value reflect.Value, options *Options, writer io.Writer) *dump
464481 w : writer ,
465482 }
466483
484+ if options .FormatTime {
485+ if options .TimeFormat != "" {
486+ result .timeFormatter = func (t time.Time ) string {
487+ return t .Format (options .TimeFormat )
488+ }
489+ } else {
490+ result .timeFormatter = func (t time.Time ) string {
491+ return t .String ()
492+ }
493+ }
494+ }
495+
467496 if options .HomePackage != "" {
468497 result .homePackageRegexp = regexp .MustCompile (fmt .Sprintf ("\\ b%s\\ ." , options .HomePackage ))
469498 }
0 commit comments