Index: service/datastore/serialize/serialize.go |
diff --git a/service/datastore/serialize/serialize.go b/service/datastore/serialize/serialize.go |
index 736010820f222499212728ca30154029a905cc4f..1f44896b3ee121da69b69d1867d72aac50ccaee6 100644 |
--- a/service/datastore/serialize/serialize.go |
+++ b/service/datastore/serialize/serialize.go |
@@ -189,16 +189,35 @@ func ReadGeoPoint(buf Buffer) (gp ds.GeoPoint, err error) { |
return |
} |
-// WriteTime writes a time.Time in a byte-sortable way. |
+// TimeToInt converts a time value to a datastore-appropraite integer value. |
// |
// This method truncates the time to microseconds and drops the timezone, |
// because that's the (undocumented) way that the appengine SDK does it. |
+func TimeToInt(t time.Time) int64 { |
+ t = t.Round(time.Microsecond) |
+ return t.Unix()*1e6 + int64(t.Nanosecond()/1e3) |
+} |
+ |
+// IntToTime converts a time integer produced by TimeToInt to a time.Time |
+// instance. |
+func IntToTime(v int64) time.Time { |
+ t := time.Unix(v/1e6, (v%1e6)*1e3) |
+ if t.IsZero() { |
+ return time.Time{} |
+ } |
+ return t.UTC() |
+} |
+ |
+// WriteTime writes a time.Time in a byte-sortable way. |
+// |
+// This method uses TimeToInt to convert the time to an integer value. This |
+// truncates the time to microseconds and drops the timezone. |
func WriteTime(buf Buffer, t time.Time) error { |
name, off := t.Zone() |
if name != "UTC" || off != 0 { |
panic(fmt.Errorf("helper: UTC OR DEATH: %s", t)) |
} |
- _, err := cmpbin.WriteInt(buf, t.Unix()*1e6+int64(t.Nanosecond()/1e3)) |
+ _, err := cmpbin.WriteInt(buf, TimeToInt(t)) |
return err |
} |
@@ -208,11 +227,7 @@ func ReadTime(buf Buffer) (time.Time, error) { |
if err != nil { |
return time.Time{}, err |
} |
- t := time.Unix(v/1e6, (v%1e6)*1e3) |
- if t.IsZero() { |
- return time.Time{}, nil |
- } |
- return t.UTC(), nil |
+ return IntToTime(v), nil |
} |
// WriteProperty writes a Property to the buffer. `context` behaves the same |