diff --git a/sonyflake/new_id.go b/sonyflake/new_id.go new file mode 100644 index 0000000..b25ce85 --- /dev/null +++ b/sonyflake/new_id.go @@ -0,0 +1,43 @@ +package sonyflake + +import ( + "errors" + "time" +) + +// NewIdByTime generates a unique ID by time. +// After the Sonyflake time overflows, NewIdByTime returns an error. +// Less than Sonyflake min time, NewIdByTime returns an error. +func (sf *Sonyflake) NewIdByTime(t time.Time) (int64, error) { + if t.UnixNano() < DefaultStartTime.UnixNano() { + return 0, errors.New("min date is 2015/01/01") + } + const maskSequence = uint16(1<= current + sf.sequence = (sf.sequence + 1) & maskSequence + if sf.sequence == 0 { + sf.elapsedTime++ + overtime := sf.elapsedTime - current + time.Sleep(sleepTimeWithNow(t, overtime)) + } + } + + return sf.toID() +} + +func sleepTimeWithNow(t time.Time, overtime int64) time.Duration { + return time.Duration(overtime)*10*time.Millisecond - + time.Duration(t.UTC().UnixNano()%sonyflakeTimeUnit)*time.Nanosecond +} + +func currentElapsedTimeWithNow(t time.Time, startTime int64) int64 { + return toSonyflakeTime(t) - startTime +} diff --git a/sonyflake/sonyflake.go b/sonyflake/sonyflake.go index 17a376b..7a04b43 100644 --- a/sonyflake/sonyflake.go +++ b/sonyflake/sonyflake.go @@ -22,7 +22,7 @@ const ( sonyflakeTimeUnit = 1e7 // nsec, i.e. 10 msec ) -var DefaultStartTime = time.Date(2020, 10, 1, 0, 0, 0, 0, time.UTC) +var DefaultStartTime = time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC) // Sonyflake is a distributed unique ID generator. type Sonyflake struct {