@@ -1163,28 +1163,43 @@ func (t Time) UnixNano() int64 {
1163
1163
return (t .unixSec ())* 1e9 + int64 (t .nsec ())
1164
1164
}
1165
1165
1166
- const timeBinaryVersion byte = 1
1166
+ const (
1167
+ timeBinaryVersionV1 byte = iota + 1 // For general situation
1168
+ timeBinaryVersionV2 // For LMT only
1169
+ )
1170
+
1171
+ var timeBinaryVersion byte
1167
1172
1168
1173
// MarshalBinary implements the encoding.BinaryMarshaler interface.
1169
1174
func (t Time ) MarshalBinary () ([]byte , error ) {
1170
1175
var offsetMin int16 // minutes east of UTC. -1 is UTC.
1176
+ var offsetSec int16
1171
1177
1172
1178
if t .Location () == UTC {
1173
1179
offsetMin = - 1
1174
1180
} else {
1175
1181
_ , offset := t .Zone ()
1176
1182
if offset % 60 != 0 {
1177
- return nil , errors .New ("Time.MarshalBinary: zone offset has fractional minute" )
1183
+ timeBinaryVersion = timeBinaryVersionV2
1184
+ offsetSec = int16 (offset % 60 )
1185
+ } else {
1186
+ timeBinaryVersion = timeBinaryVersionV1
1187
+ if offset % 60 != 0 {
1188
+ return nil , errors .New ("Time.MarshalBinary: zone offset has fractional minute" )
1189
+ }
1178
1190
}
1191
+
1179
1192
offset /= 60
1180
1193
if offset < - 32768 || offset == - 1 || offset > 32767 {
1181
1194
return nil , errors .New ("Time.MarshalBinary: unexpected zone offset" )
1182
1195
}
1196
+
1183
1197
offsetMin = int16 (offset )
1184
1198
}
1185
1199
1186
1200
sec := t .sec ()
1187
1201
nsec := t .nsec ()
1202
+
1188
1203
enc := []byte {
1189
1204
timeBinaryVersion , // byte 0 : version
1190
1205
byte (sec >> 56 ), // bytes 1-8: seconds
@@ -1202,6 +1217,9 @@ func (t Time) MarshalBinary() ([]byte, error) {
1202
1217
byte (offsetMin >> 8 ), // bytes 13-14: zone offset in minutes
1203
1218
byte (offsetMin ),
1204
1219
}
1220
+ if timeBinaryVersion == timeBinaryVersionV2 {
1221
+ enc = append (enc , byte (offsetSec >> 8 ), byte (offsetSec ))
1222
+ }
1205
1223
1206
1224
return enc , nil
1207
1225
}
@@ -1216,9 +1234,16 @@ func (t *Time) UnmarshalBinary(data []byte) error {
1216
1234
if buf [0 ] != timeBinaryVersion {
1217
1235
return errors .New ("Time.UnmarshalBinary: unsupported version" )
1218
1236
}
1237
+ timeVersion := buf [0 ]
1219
1238
1220
- if len (buf ) != /*version*/ 1 + /*sec*/ 8 + /*nsec*/ 4 + /*zone offset*/ 2 {
1221
- return errors .New ("Time.UnmarshalBinary: invalid length" )
1239
+ if buf [0 ] == timeBinaryVersionV1 {
1240
+ if len (buf ) != /*version*/ 1 + /*sec*/ 8 + /*nsec*/ 4 + /*zone offset*/ 2 {
1241
+ return errors .New ("Time.UnmarshalBinary: invalid length" )
1242
+ }
1243
+ } else if buf [0 ] == timeBinaryVersionV2 {
1244
+ if len (buf ) != /*version*/ 1 + /*sec*/ 8 + /*nsec*/ 4 + /*zone offset*/ 4 {
1245
+ return errors .New ("Time.UnmarshalBinary: invalid length" )
1246
+ }
1222
1247
}
1223
1248
1224
1249
buf = buf [1 :]
@@ -1229,7 +1254,13 @@ func (t *Time) UnmarshalBinary(data []byte) error {
1229
1254
nsec := int32 (buf [3 ]) | int32 (buf [2 ])<< 8 | int32 (buf [1 ])<< 16 | int32 (buf [0 ])<< 24
1230
1255
1231
1256
buf = buf [4 :]
1232
- offset := int (int16 (buf [1 ])| int16 (buf [0 ])<< 8 ) * 60
1257
+ var offset int
1258
+ if timeVersion == timeBinaryVersionV2 {
1259
+ offset = int (int16 (buf [1 ])| int16 (buf [0 ])<< 8 )* 60 + int (int16 (buf [3 ])| int16 (buf [2 ])<< 8 )
1260
+ } else {
1261
+ // timeVersion is equal to timeBinaryVersionV1
1262
+ offset = int (int16 (buf [1 ])| int16 (buf [0 ])<< 8 ) * 60
1263
+ }
1233
1264
1234
1265
* t = Time {}
1235
1266
t .wall = uint64 (nsec )
0 commit comments