diff --git a/uuid_test.go b/uuid_test.go index 906ecbe..9c4c7f0 100644 --- a/uuid_test.go +++ b/uuid_test.go @@ -928,3 +928,25 @@ func TestVersion7MonotonicityStrict(t *testing.T) { u1 = u2 } } + +func unixMilli(msec int64) time.Time { + return time.Unix(msec/1e3, (msec%1e3)*1e6) +} + +func TestVersion7MaxTime(t *testing.T) { + timeNow = func() time.Time { + return unixMilli((1 << 48) - 1) // max time for uuid v7 + } + defer func() { + timeNow = time.Now + }() + + SetRand(fakeRand{}) + defer SetRand(nil) + + u := Must(NewV7()) + want := "ffffffff-ffff-7000-8888-888888888888" + if u.String() != want { + t.Errorf("time overflow: got %q, want %q", u.String(), want) + } +} diff --git a/version7.go b/version7.go index 3fec671..938c11e 100644 --- a/version7.go +++ b/version7.go @@ -89,10 +89,11 @@ func getV7Time() (milli, seq int64) { timeMu.Lock() defer timeMu.Unlock() - nano := timeNow().UnixNano() - milli = nano / nanoPerMilli + t := timeNow() + nano := t.Nanosecond() + milli = t.Unix()*1e3 + int64(nano/nanoPerMilli) // Sequence number is between 0 and 3906 (nanoPerMilli>>8) - seq = (nano - milli*nanoPerMilli) >> 8 + seq = int64(nano%nanoPerMilli) >> 8 now := milli<<12 + seq if now <= lastV7time { now = lastV7time + 1