Convert time readers to represent time in UTC.

Go's time.Time represents time as UTC in its fundamental data type.
That said, when using ``time.Unix(...)``, it sets the zone for the
time representation to the local.  Unfortunately with diagnosis and
our tests, it is a PITA to jump between various zones, even though
the serialized version remains the same.

To keep things easy, all places where times are generated or read
are converted into UTC.  These conversions are cheap, for
``Time.In`` merely changes a pointer reference in the struct,
nothing more.  This enables me to diagnose test failures with fixture
data very easily.
This commit is contained in:
Matt T. Proud 2013-04-24 12:05:52 +02:00
parent 955708e8db
commit e86f4d9dfd
5 changed files with 12 additions and 10 deletions

View file

@ -18,14 +18,14 @@ import (
"time" "time"
) )
var ( // EncodeTimeInto writes the provided time into the specified buffer subject
EarliestTime = EncodeTime(time.Time{}) // to the LevelDB big endian key sort order requirement.
)
func EncodeTimeInto(dst []byte, t time.Time) { func EncodeTimeInto(dst []byte, t time.Time) {
binary.BigEndian.PutUint64(dst, uint64(t.Unix())) binary.BigEndian.PutUint64(dst, uint64(t.Unix()))
} }
// EncodeTime converts the provided time into a byte buffer subject to the
// LevelDB big endian key sort order requirement.
func EncodeTime(t time.Time) []byte { func EncodeTime(t time.Time) []byte {
buffer := make([]byte, 8) buffer := make([]byte, 8)
@ -34,6 +34,8 @@ func EncodeTime(t time.Time) []byte {
return buffer return buffer
} }
// DecodeTime deserializes a big endian byte array into a Unix time in UTC,
// omitting granularity precision less than a second.
func DecodeTime(src []byte) time.Time { func DecodeTime(src []byte) time.Time {
return time.Unix(int64(binary.BigEndian.Uint64(src)), 0) return time.Unix(int64(binary.BigEndian.Uint64(src)), 0).UTC()
} }

View file

@ -139,7 +139,7 @@ func (v Values) InsideInterval(t time.Time) (s bool) {
func NewValuesFromDTO(dto *dto.SampleValueSeries) (v Values) { func NewValuesFromDTO(dto *dto.SampleValueSeries) (v Values) {
for _, value := range dto.Value { for _, value := range dto.Value {
v = append(v, SamplePair{ v = append(v, SamplePair{
Timestamp: time.Unix(*value.Timestamp, 0), Timestamp: time.Unix(*value.Timestamp, 0).UTC(),
Value: SampleValue(*value.Value), Value: SampleValue(*value.Value),
}) })
} }

View file

@ -73,7 +73,7 @@ func NewSampleKeyFromDTO(dto *dto.SampleKey) SampleKey {
return SampleKey{ return SampleKey{
Fingerprint: NewFingerprintFromDTO(dto.Fingerprint), Fingerprint: NewFingerprintFromDTO(dto.Fingerprint),
FirstTimestamp: indexable.DecodeTime(dto.Timestamp), FirstTimestamp: indexable.DecodeTime(dto.Timestamp),
LastTimestamp: time.Unix(*dto.LastTimestamp, 0), LastTimestamp: time.Unix(*dto.LastTimestamp, 0).UTC(),
SampleCount: *dto.SampleCount, SampleCount: *dto.SampleCount,
} }
} }

View file

@ -37,7 +37,7 @@ func (w Watermark) ToMetricHighWatermarkDTO() *dto.MetricHighWatermark {
// dto.MetricHighWatermark object. // dto.MetricHighWatermark object.
func NewWatermarkFromHighWatermarkDTO(d *dto.MetricHighWatermark) Watermark { func NewWatermarkFromHighWatermarkDTO(d *dto.MetricHighWatermark) Watermark {
return Watermark{ return Watermark{
time.Unix(*d.Timestamp, 0), time.Unix(*d.Timestamp, 0).UTC(),
} }
} }

View file

@ -84,8 +84,8 @@ func (serv MetricsService) QueryRange(expr string, end int64, duration int64, st
matrix, err := ast.EvalVectorRange( matrix, err := ast.EvalVectorRange(
exprNode.(ast.VectorNode), exprNode.(ast.VectorNode),
time.Unix(end-duration, 0), time.Unix(end-duration, 0).UTC(),
time.Unix(end, 0), time.Unix(end, 0).UTC(),
time.Duration(step)*time.Second) time.Duration(step)*time.Second)
if err != nil { if err != nil {
return ast.ErrorToJSON(err) return ast.ErrorToJSON(err)