2

I have a map that is defined like:

mapMeasures := make(map[time.Time]models.Measure, 0)

with

type Measure struct {
    Delta         float64      // I just let one field to simplificate
}

So the initial loop will fill values from 22/01/20-10:10:00 to 22/01/20-12:00:00, so it will store 12 keys value (10 minutes timestep)

Then, it will loop again those timestamp, and add delta to existing value.

So, I need to check if there is already a key corresponding to my actual timestamp:

if val, ok := mapMeasures[ts]; ok { // ts already exists, we must sum delta values
    measure.Delta += val.Delta
}

But it appears this condition is never true.

I debugged the code, and I can see the timestamp is actually present inside map:

 mapMeasures = {map[time.Time]gitlab.com/company/common/models.Measure} 
 0 =  -> 
  key = {time.Time} 2020-01-22 11:40:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132460} 
 1 =  -> 
  key = {time.Time} 2020-01-22 12:30:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132780} 
 2 =  -> 
  key = {time.Time} 2020-01-22 12:50:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc0001328c0} 
 3 =  -> 
  key = {time.Time} 2020-01-22 11:00:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132140} 
 4 =  -> 
  key = {time.Time} 2020-01-22 11:10:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132280} 
 5 =  -> 
  key = {time.Time} 2020-01-22 11:20:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132320} 
 6 =  -> 
  key = {time.Time} 2020-01-22 11:30:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc0001323c0} 
 7 =  -> 
  key = {time.Time} 2020-01-22 11:50:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132500} 
 8 =  -> 
  key = {time.Time} 2020-01-22 12:00:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc0001325a0} 
 9 =  -> 
  key = {time.Time} 2020-01-22 12:10:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132640} 
 10 =  -> 
  key = {time.Time} 2020-01-22 12:20:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc0001326e0} 
 11 =  -> 
  key = {time.Time} 2020-01-22 12:40:00 +0100
  value = {*gitlab.com/company/common/models.Measure | 0xc000132820} 

Actual ts:

{time.Time} 2020-01-22 11:00:00 +0100

Is there any issue with a key to be a timestamp ? Should I convert it to a string, or int ???

icza
  • 389,944
  • 63
  • 907
  • 827
Juliatzin
  • 18,455
  • 40
  • 166
  • 325

1 Answers1

8

Quoting from time.Time:

Note that the Go == operator compares not just the time instant but also the Location and the monotonic clock reading. Therefore, Time values should not be used as map or database keys without first guaranteeing that the identical Location has been set for all values, which can be achieved through use of the UTC or Local method, and that the monotonic clock reading has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) to t == u, since t.Equal uses the most accurate comparison available and correctly handles the case when only one of its arguments has a monotonic clock reading.

Do not use time.Time as map keys, instead use the Unix timestamp returned by Time.Unix(). The Unix timestamp is location and monotonic clock reading "free".

If your keys must also include the location (time zone), then use a struct which includes the Unix timestamp and the zone offset, e.g.:

type Key {
    ts     int64
    offset int
}

See related question: Why do 2 time structs with the same date and time return false when compared with ==?

icza
  • 389,944
  • 63
  • 907
  • 827