@@ 160,4 160,53 @@ Now we’ll handle epoch-based timestamps: those are scalar values where 0
corresponds to the epoch (January 1, 1970), they can either be integer or
floating point values.
+We’ll minimize the size of our output by picking the most compact type we can
+use with our encoder. The timestamp can either be an integer, a floating point
+number, or a RFC3339 string. If there’s a timestamp’s timezone isn’t UTC we’ll
+have to use the largest type: the RFC3339 string, because we need to encode the
+timezone. If the timestamp’s timezone is UTC we can use a scalar timestamp
+because we don’t have to set the timezone because it’s assumed to be UTC. We’ll
+use an integer when the timestamp can be represented as whole seconds and use
+floating point number eitherwise.
+First we’ll add a condition to only use RFC3339 strings when the timestamp has a
+timezone that’s not UTC.
+
+ func (e *Encoder) writeTime(v reflect.Value) error {
+ var t = v.Interface().(time.Time)
+ if t.Location() != time.UTC && t.Location() != nil {
+ if err := e.writeHeader(majorTag, minorTimeString); err != nil {
+ return err
+ }
+ return e.writeUnicodeString(t.Format(time.RFC3339))
+ }
+ return ErrNotImplemented
+ }
+
+Because we’re changing the behavior of writeTime when the timezone is UTC, we
+need to fix the test to use timestamp with its timezone set. To do so we replace
+the Z at the end of rfc3339Timestamp with +07:00:
+
+ func TestTimestamp(t *testing.T) {
+ var rfc3339Timestamp, _ = time.Parse(time.RFC3339, "2013-03-21T20:04:00+07:00")
+
+ var cases = []struct {
+ Value time.Time
+ Expected []byte
+ }{
+ {
+ Value: rfc3339Timestamp,
+ Expected: []byte{
+ 0xc0, 0x78, 0x19, 0x32, 0x30, 0x31, 0x33, 0x2d, 0x30, 0x33, 0x2d,
+ 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x30,
+ '+', '0', '7', ':', '0', '0',
+ },
+ },
+ }
+
+ for _, c := range cases {
+ t.Run(fmt.Sprintf("%v", c.Value), func(t *testing.T) {
+ testEncoder(t, c.Value, c.Expected)
+ })
+ }
+ }
@@ 241,8 241,8 @@ func (e *Encoder) writeTime(v reflect.Va
}
return e.writeInteger(sign, uint64(unixTime))
} else {
- var unixTime = float64(unixTimeNano) / float64(nanoSecondsInSecond)
- return e.writeFloat(unixTime)
+ return e.writeFloat(
+ float64(unixTimeNano) / float64(nanoSecondsInSecond))
}
}