fix: generate all slot timestamps in optimizer asTimestamps#28258
Closed
rishabhvaish wants to merge 2 commits intoevcc-io:masterfrom
Closed
fix: generate all slot timestamps in optimizer asTimestamps#28258rishabhvaish wants to merge 2 commits intoevcc-io:masterfrom
rishabhvaish wants to merge 2 commits intoevcc-io:masterfrom
Conversation
The loop condition was based on len(res) which is always 1 after the initial append, so the loop body never executed. This caused asTimestamps to return only the first slot's timestamp instead of one timestamp per optimization slot. Additionally, the timestamps were not accumulated- each was independently offset from end-of-hour rather than building on the previous slot's end time.
Contributor
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The new cumulative logic in
asTimestampsusesdt[0]twice (once in the initialtsand again as the firstdin the loop), which means the second timestamp is offset bydt[0]from the first rather than starting from the first slot’s start; consider iterating overdt[1:]after initializingtsfromdt[0]to match the described behavior. - For the empty
dtcase, consider returning an empty slice instead ofnilso callers that iterate or append to the result don’t need to treat the zero-length case specially.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new cumulative logic in `asTimestamps` uses `dt[0]` twice (once in the initial `ts` and again as the first `d` in the loop), which means the second timestamp is offset by `dt[0]` from the first rather than starting from the first slot’s start; consider iterating over `dt[1:]` after initializing `ts` from `dt[0]` to match the described behavior.
- For the empty `dt` case, consider returning an empty slice instead of `nil` so callers that iterate or append to the result don’t need to treat the zero-length case specially.
## Individual Comments
### Comment 1
<location path="core/site_optimizer.go" line_range="624-625" />
<code_context>
- res = append(res, eoh.Add(-time.Duration(dt[0])*time.Second))
- for i := range len(res) - 1 {
- res = append(res, eoh.Add(time.Duration(dt[i+1])*time.Second))
+ ts := eoh.Add(-time.Duration(dt[0]) * time.Second)
+ for _, d := range dt {
+ res = append(res, ts)
+ ts = ts.Add(time.Duration(d) * time.Second)
</code_context>
<issue_to_address>
**issue (bug_risk):** The new loop mixes an initial absolute offset with cumulative deltas, which likely produces incorrect timestamps.
Previously, each timestamp was computed as an independent offset from `eoh` (`eoh.Add(-dt[0])`, then `eoh.Add(dt[i+1])`). The new code sets `ts = eoh - dt[0]` once, then appends `ts` for every element in `dt` while cumulatively adding `d`, so you effectively apply `dt[0]` twice and switch from absolute offsets to cumulative deltas.
If `dt` is meant to be absolute offsets, keep computing each timestamp directly from `eoh`, e.g.:
```go
for _, d := range dt {
res = append(res, eoh.Add(-time.Duration(d)*time.Second))
}
```
If `dt` is meant to be deltas between timestamps, start the loop from `dt[1:]` (so `dt[0]` is only used to init `ts`) and confirm that this cumulative sequence matches the intended timeline.
</issue_to_address>
### Comment 2
<location path="core/site_optimizer.go" line_range="618-619" />
<code_context>
}
func asTimestamps(dt []int) []time.Time {
+ if len(dt) == 0 {
+ return nil
+ }
+
</code_context>
<issue_to_address>
**suggestion:** Returning nil for empty input changes the previous behavior and may affect callers expecting a non-nil empty slice.
Previously, when `len(dt) == 0`, this function returned a non-nil empty slice; now it returns `nil`. In Go this can change behavior (e.g., JSON output, equality checks, or callers that rely on a non-nil slice while expecting `len(asTimestamps(...)) == 0`). If there’s no deliberate need for `nil`, consider returning `[]time.Time{}` here to keep the existing contract.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
andig
reviewed
Mar 16, 2026
| } | ||
|
|
||
| func asTimestamps(dt []int) []time.Time { | ||
| if len(dt) == 0 { |
Contributor
Author
There was a problem hiding this comment.
Good point, removed it. The only caller always passes a non-empty slice so the guard was dead code.
Member
If that's the case, the only required change is apparently so why change everything else? Please make sure to also add a test. |
The only caller always passes a non-empty slice from timeSteps(minLen) where minLen >= 8, so the guard is unreachable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Rishabh Vaish <rishabhvaish.904@gmail.com>
Member
|
Closed in d2a8813 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
asTimestampsonly returned 1 timestamp instead of one per slot. The loopfor i := range len(res) - 1evaluated torange 0sincelen(res)was always 1, so it never executed. Timestamp offsets also weren't cumulative.Rewrote to iterate over all
dtentries and accumulate timestamps from the first slot's start time.Test plan
go test ./core/... -vpasses🤖 Generated with Claude Code