HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoMinor

Random timestamp within last 3 relative years

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
randomlastwithintimestampyearsrelative

Problem

I'm trying to generate a random time between now and 3 years ago. To my knowledge, Go doesn't have a random(min,max) feature in either math/rand or crypto/rand where min > 0. To naively combat that, I generate a slice containing every time stamp within the relative now and 3 years ago, and then select the index at random with rand.Intn(len(timeRange)), because I am guaranteed to get a random index between 0 and len(timeRange). It works just fine, and I get a Unix time stamp sometime between now and 3 years ago. However, I want to generate just one timestamp, not ~94m of them and then randomly picking one...it's egregiously slow.

Here is the code:

package main

import (
    "time"
    "math/rand"
    "fmt"
)

func randomTimestamp() time.Time {
    now := time.Now().Unix()
    threeYearsAgo := int64(now - 94608000)
    timeRange := make([]int64,1)
    for i := threeYearsAgo; i < now; i++ {
        timeRange = append(timeRange, i)
    }
    randomTime := rand.Intn(len(timeRange))

    randomNow := time.Unix(timeRange[randomTime], 0)

    return randomNow
}

func main() {
    for i := 0; i < 25; i++ {
        fmt.Println(randomTimestamp().Format(time.RFC3339))
    }
}


How can I optimise randomTimestamp() so it doesn't have to calculate every second over the last 3 years, but it randomly picks one between now and 3 years ago?

Solution

As Darren H has said in the comments, just generate a random number between 0 and nanoseconds in three years, and subtract from time.Now():

const threeYears = 3 * 365 * 24 * time.Hour

func main() {
    rand.Seed(time.Now().UnixNano())
    d := time.Duration(rand.Int63n(int64(threeYears)))
    fmt.Println(time.Now().Add(-d))
}

Code Snippets

const threeYears = 3 * 365 * 24 * time.Hour

func main() {
    rand.Seed(time.Now().UnixNano())
    d := time.Duration(rand.Int63n(int64(threeYears)))
    fmt.Println(time.Now().Add(-d))
}

Context

StackExchange Code Review Q#148805, answer score: 2

Revisions (0)

No revisions yet.