Get floor of a time window

Viewed 371

I am attempting to port over some Python code into Go. I want to be able to pass in a duration and then get the floor based on the current time. For example if the time was 12:35:53 and I passed in 5s the floor would be 12:35:50, I also need to be able to pass in a step value so if I pass in -1 it will step back to the previous 5 second floor, for example if the time was 12:35:53 it will roll back to 12:35:45.

The Python code is as follows

window_length_as_seconds = window_length.total_seconds()
t = time()
remainder = t % window_length_as_seconds
window_start = t - remainder + step * window_length_as_seconds
return datetime.datetime.utcfromtimestamp(window_start)

Here is a link to my go code with an example

https://play.golang.org/p/wefXOuLMNE7

func GetWindow(windowLength time.Duration, step int64) time.Time {
    now := Now().Unix()
    remainder := now % int64(windowLength.Seconds())
    windowStart := time.Unix(now-(remainder+step*int64(windowLength.Seconds())), 0)
    return windowStart.UTC()
}

It works fine if I pass in seconds without a step however with the step it steps the opposite way and when I pass in a fraction of a second for example If I set the duration as "100ms" I get the following error:

panic: runtime error: integer divide by zero

Am I dealing with times in Go incorrectly compared to the Python?

1 Answers

If you want to round-down time, use time.Truncate:

t := time.Now()
fmt.Println(t.Truncate(5*time.Second))

Applying this for your needs:

// returns in UTC timezone - regardless of input timezone
func getWindow(t time.Time, windowLength time.Duration, step int64) time.Time {
    return t.UTC().Truncate(windowLength).Add(
        time.Duration(step) * windowLength,
    )
}

// time.Now() may be in any timezone - but UTC will be returned (see above)
func GetWindow(windowLength time.Duration, step int64) time.Time {
    return getWindow(time.Now(), windowLength, step)
}

Demo with alternative timezones etc.: https://play.golang.org/p/gqsT4LvWdDi

Adding to your test code: https://play.golang.org/p/UDPlsR6IGPw

Related