Skip to content

Commit

Permalink
implement TimestampFromV7 (#125)
Browse files Browse the repository at this point in the history
closes #123
  • Loading branch information
dropwhile committed Sep 19, 2023
1 parent 8318aa5 commit 22c52c2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
26 changes: 26 additions & 0 deletions uuid.go
Expand Up @@ -131,6 +131,32 @@ func TimestampFromV6(u UUID) (Timestamp, error) {
return Timestamp(uint64(low) + (uint64(mid) << 12) + (uint64(hi) << 28)), nil
}

// TimestampFromV7 returns the Timestamp embedded within a V7 UUID. This
// function returns an error if the UUID is any version other than 7.
//
// This is implemented based on revision 03 of the Peabody UUID draft, and may
// be subject to change pending further revisions. Until the final specification
// revision is finished, changes required to implement updates to the spec will
// not be considered a breaking change. They will happen as a minor version
// releases until the spec is final.
func TimestampFromV7(u UUID) (Timestamp, error) {
if u.Version() != 7 {
return 0, fmt.Errorf("uuid: %s is version %d, not version 6", u, u.Version())
}

t := 0 |
(int64(u[0]) << 40) |
(int64(u[1]) << 32) |
(int64(u[2]) << 24) |
(int64(u[3]) << 16) |
(int64(u[4]) << 8) |
int64(u[5])

// convert to format expected by Timestamp
tsNanos := epochStart + time.UnixMilli(t).UTC().UnixNano()/100
return Timestamp(tsNanos), nil
}

// Nil is the nil UUID, as specified in RFC-4122, that has all 128 bits set to
// zero.
var Nil = UUID{}
Expand Down
25 changes: 25 additions & 0 deletions uuid_test.go
Expand Up @@ -256,6 +256,31 @@ func TestTimestampFromV6(t *testing.T) {
}
}

func TestTimestampFromV7(t *testing.T) {
tests := []struct {
u UUID
want Timestamp
wanterr bool
}{
{u: Must(NewV1()), wanterr: true},
// v7 is unix_ts_ms, so zero value time is unix epoch
{u: Must(FromString("00000000-0000-7000-0000-000000000000")), want: 122192928000000000},
{u: Must(FromString("018a8fec-3ced-7164-995f-93c80cbdc575")), want: 139139245386050000},
{u: Must(FromString("ffffffff-ffff-7fff-ffff-ffffffffffff")), want: Timestamp(epochStart + time.UnixMilli((1<<48)-1).UTC().UnixNano()/100)},
}
for _, tt := range tests {
got, err := TimestampFromV7(tt.u)

switch {
case tt.wanterr && err == nil:
t.Errorf("TimestampFromV7(%v) want error, got %v", tt.u, got)

case tt.want != got:
t.Errorf("TimestampFromV7(%v) got %v, want %v", tt.u, got, tt.want)
}
}
}

func BenchmarkFormat(b *testing.B) {
var tests = []string{
"%s",
Expand Down

0 comments on commit 22c52c2

Please sign in to comment.