Просмотр исходного кода

Fixes UUID Timestamp, also adds FromTime function

Fixes bug where nanoseconds were not being pulled out of the 60-bit
UUID time correctly. Cleans up that code to use timeBase rather than a
special hex value.

Also adds FromTime function to generate Type 1 UUIDs from arbitrary
times.
Pete Hopkins 12 лет назад
Родитель
Сommit
5055479f14
2 измененных файлов с 29 добавлено и 9 удалено
  1. 12 9
      uuid/uuid.go
  2. 17 0
      uuid/uuid_test.go

+ 12 - 9
uuid/uuid.go

@@ -100,14 +100,19 @@ func RandomUUID() UUID {
 
 
 var timeBase = time.Date(1582, time.October, 15, 0, 0, 0, 0, time.UTC).Unix()
 var timeBase = time.Date(1582, time.October, 15, 0, 0, 0, 0, time.UTC).Unix()
 
 
-// TimeUUID generates a new time based UUID (version 1) as described in RFC
+// Convenience to generate a version 1 UUID from the current time.
+func TimeUUID() UUID {
+	return FromTime(time.Now())
+}
+
+// FromTime generates a new time based UUID (version 1) as described in RFC
 // 4122. This UUID contains the MAC address of the node that generated the
 // 4122. This UUID contains the MAC address of the node that generated the
 // UUID, a timestamp and a sequence number.
 // UUID, a timestamp and a sequence number.
-func TimeUUID() UUID {
+func FromTime(aTime time.Time) UUID {
 	var u UUID
 	var u UUID
 
 
-	now := time.Now().In(time.UTC)
-	t := uint64(now.Unix()-timeBase)*10000000 + uint64(now.Nanosecond()/100)
+	utcTime := aTime.In(time.UTC)
+	t := uint64(utcTime.Unix()-timeBase)*10000000 + uint64(utcTime.Nanosecond()/100)
 	u[0], u[1], u[2], u[3] = byte(t>>24), byte(t>>16), byte(t>>8), byte(t)
 	u[0], u[1], u[2], u[3] = byte(t>>24), byte(t>>16), byte(t>>8), byte(t)
 	u[4], u[5] = byte(t>>40), byte(t>>32)
 	u[4], u[5] = byte(t>>40), byte(t>>32)
 	u[6], u[7] = byte(t>>56)&0x0F, byte(t>>48)
 	u[6], u[7] = byte(t>>56)&0x0F, byte(t>>48)
@@ -187,10 +192,8 @@ func (u UUID) Time() time.Time {
 	if u.Version() != 1 {
 	if u.Version() != 1 {
 		return time.Time{}
 		return time.Time{}
 	}
 	}
-	t := u.Timestamp() - timeEpoch
+	t := u.Timestamp()
 	sec := t / 1e7
 	sec := t / 1e7
-	nsec := t - sec
-	return time.Unix(int64(sec), int64(nsec)).UTC()
+	nsec := t % 1e7
+	return time.Unix(sec+timeBase, nsec).UTC()
 }
 }
-
-var timeEpoch int64 = 0x01B21DD213814000

+ 17 - 0
uuid/uuid_test.go

@@ -7,6 +7,7 @@ package uuid
 import (
 import (
 	"bytes"
 	"bytes"
 	"testing"
 	"testing"
+	"time"
 )
 )
 
 
 func TestNil(t *testing.T) {
 func TestNil(t *testing.T) {
@@ -74,6 +75,22 @@ func TestRandomUUID(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestFromTime(t *testing.T) {
+	date := time.Date(1982, 5, 5, 12, 34, 56, 0, time.UTC)
+	uuid := FromTime(date)
+
+	if uuid.Time() != date {
+		t.Errorf("embedded time incorrect. Expected %v got %v", date, uuid.Time())
+	}
+}
+
+func TestParse(t *testing.T) {
+	uuid, _ := ParseUUID("486f3a88-775b-11e3-ae07-d231feb1dc81")
+	if uuid.Time().Truncate(time.Second) != time.Date(2014, 1, 7, 5, 19, 29, 0, time.UTC) {
+		t.Errorf("Expected date of 1/7/2014 at 5:19:29, got %v", uuid.Time())
+	}
+}
+
 func TestTimeUUID(t *testing.T) {
 func TestTimeUUID(t *testing.T) {
 	var node []byte
 	var node []byte
 	timestamp := int64(0)
 	timestamp := int64(0)