From 1e26916bf6bd4e97ae02327053532cf32fc169a0 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Thu, 9 Jan 2020 16:05:21 -0600 Subject: [PATCH] Add getTimestamp() and getClockSeq() to FieldsInterface --- src/Guid/Fields.php | 17 +++++++++++++++++ src/Nonstandard/Fields.php | 17 +++++++++++++++++ src/Rfc4122/Fields.php | 17 +++++++++++++++++ src/Rfc4122/FieldsInterface.php | 11 +++++++++++ tests/Guid/FieldsTest.php | 10 ++++++++++ tests/Nonstandard/FieldsTest.php | 2 ++ tests/Rfc4122/FieldsTest.php | 10 ++++++++++ 7 files changed, 84 insertions(+) diff --git a/src/Guid/Fields.php b/src/Guid/Fields.php index e94996a..3705f8a 100644 --- a/src/Guid/Fields.php +++ b/src/Guid/Fields.php @@ -119,6 +119,23 @@ final class Fields implements FieldsInterface return (string) ($hex[1] ?? ''); } + public function getTimestamp(): string + { + return sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()) & 0x0fff, + $this->getTimeMid(), + $this->getTimeLow() + ); + } + + public function getClockSeq(): string + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + } + public function getClockSeqHiAndReserved(): string { return bin2hex(substr($this->bytes, 8, 1)); diff --git a/src/Nonstandard/Fields.php b/src/Nonstandard/Fields.php index da72797..8f56573 100644 --- a/src/Nonstandard/Fields.php +++ b/src/Nonstandard/Fields.php @@ -63,6 +63,13 @@ final class Fields implements FieldsInterface return $this->bytes; } + public function getClockSeq(): string + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + } + public function getClockSeqHiAndReserved(): string { return bin2hex(substr($this->bytes, 8, 1)); @@ -93,6 +100,16 @@ final class Fields implements FieldsInterface return bin2hex(substr($this->bytes, 4, 2)); } + public function getTimestamp(): string + { + return sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()) & 0x0fff, + $this->getTimeMid(), + $this->getTimeLow() + ); + } + public function getVersion(): ?int { return null; diff --git a/src/Rfc4122/Fields.php b/src/Rfc4122/Fields.php index 87a8d65..405313f 100644 --- a/src/Rfc4122/Fields.php +++ b/src/Rfc4122/Fields.php @@ -74,6 +74,13 @@ final class Fields implements FieldsInterface return $this->bytes; } + public function getClockSeq(): string + { + $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; + + return str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT); + } + public function getClockSeqHiAndReserved(): string { return bin2hex(substr($this->bytes, 8, 1)); @@ -104,6 +111,16 @@ final class Fields implements FieldsInterface return bin2hex(substr($this->bytes, 4, 2)); } + public function getTimestamp(): string + { + return sprintf( + '%03x%04s%08s', + hexdec($this->getTimeHiAndVersion()) & 0x0fff, + $this->getTimeMid(), + $this->getTimeLow() + ); + } + public function getVersion(): ?int { if ($this->isNil()) { diff --git a/src/Rfc4122/FieldsInterface.php b/src/Rfc4122/FieldsInterface.php index 172a6ad..782b6b9 100644 --- a/src/Rfc4122/FieldsInterface.php +++ b/src/Rfc4122/FieldsInterface.php @@ -38,6 +38,12 @@ use Ramsey\Uuid\Fields\FieldsInterface as BaseFieldsInterface; */ interface FieldsInterface extends BaseFieldsInterface { + /** + * Returns the full 16-bit clock sequence, with the variant bits (two most + * significant bits) masked out + */ + public function getClockSeq(): string; + /** * Returns the high field of the clock sequence multiplexed with the variant */ @@ -68,6 +74,11 @@ interface FieldsInterface extends BaseFieldsInterface */ public function getTimeMid(): string; + /** + * Returns the full 60-bit timestamp, without the version + */ + public function getTimestamp(): string; + /** * Returns the variant * diff --git a/tests/Guid/FieldsTest.php b/tests/Guid/FieldsTest.php index bef27ae..1618cf7 100644 --- a/tests/Guid/FieldsTest.php +++ b/tests/Guid/FieldsTest.php @@ -115,56 +115,66 @@ class FieldsTest extends TestCase // representations, which are never in GUID byte order. return [ // For ff6f8cb0-c57d-11e1-cb21-0800200c9a66 + ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeq', '0b21'], ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqHiAndReserved', 'cb'], ['b08c6fff7dc5e111cb210800200c9a66', 'getClockSeqLow', '21'], ['b08c6fff7dc5e111cb210800200c9a66', 'getNode', '0800200c9a66'], ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeHiAndVersion', '11e1'], ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['b08c6fff7dc5e111cb210800200c9a66', 'getTimeMid', 'c57d'], + ['b08c6fff7dc5e111cb210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['b08c6fff7dc5e111cb210800200c9a66', 'getVariant', 6], ['b08c6fff7dc5e111cb210800200c9a66', 'getVersion', 1], ['b08c6fff7dc5e111cb210800200c9a66', 'isNil', false], // For ff6f8cb0-c57d-41e1-db21-0800200c9a66 + ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeq', '1b21'], ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqHiAndReserved', 'db'], ['b08c6fff7dc5e141db210800200c9a66', 'getClockSeqLow', '21'], ['b08c6fff7dc5e141db210800200c9a66', 'getNode', '0800200c9a66'], ['b08c6fff7dc5e141db210800200c9a66', 'getTimeHiAndVersion', '41e1'], ['b08c6fff7dc5e141db210800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['b08c6fff7dc5e141db210800200c9a66', 'getTimeMid', 'c57d'], + ['b08c6fff7dc5e141db210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['b08c6fff7dc5e141db210800200c9a66', 'getVariant', 6], ['b08c6fff7dc5e141db210800200c9a66', 'getVersion', 4], ['b08c6fff7dc5e141db210800200c9a66', 'isNil', false], // For ff6f8cb0-c57d-31e1-8b21-0800200c9a66 + ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeq', '0b21'], ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqHiAndReserved', '8b'], ['b08c6fff7dc5e1318b210800200c9a66', 'getClockSeqLow', '21'], ['b08c6fff7dc5e1318b210800200c9a66', 'getNode', '0800200c9a66'], ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeHiAndVersion', '31e1'], ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['b08c6fff7dc5e1318b210800200c9a66', 'getTimeMid', 'c57d'], + ['b08c6fff7dc5e1318b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['b08c6fff7dc5e1318b210800200c9a66', 'getVariant', 2], ['b08c6fff7dc5e1318b210800200c9a66', 'getVersion', 3], ['b08c6fff7dc5e1318b210800200c9a66', 'isNil', false], // For ff6f8cb0-c57d-51e1-9b21-0800200c9a66 + ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeq', '1b21'], ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqHiAndReserved', '9b'], ['b08c6fff7dc5e1519b210800200c9a66', 'getClockSeqLow', '21'], ['b08c6fff7dc5e1519b210800200c9a66', 'getNode', '0800200c9a66'], ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeHiAndVersion', '51e1'], ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['b08c6fff7dc5e1519b210800200c9a66', 'getTimeMid', 'c57d'], + ['b08c6fff7dc5e1519b210800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['b08c6fff7dc5e1519b210800200c9a66', 'getVariant', 2], ['b08c6fff7dc5e1519b210800200c9a66', 'getVersion', 5], ['b08c6fff7dc5e1519b210800200c9a66', 'isNil', false], // For 00000000-0000-0000-0000-000000000000 + ['00000000000000000000000000000000', 'getClockSeq', '0000'], ['00000000000000000000000000000000', 'getClockSeqHiAndReserved', '00'], ['00000000000000000000000000000000', 'getClockSeqLow', '00'], ['00000000000000000000000000000000', 'getNode', '000000000000'], ['00000000000000000000000000000000', 'getTimeHiAndVersion', '0000'], ['00000000000000000000000000000000', 'getTimeLow', '00000000'], ['00000000000000000000000000000000', 'getTimeMid', '0000'], + ['00000000000000000000000000000000', 'getTimestamp', '000000000000000'], ['00000000000000000000000000000000', 'getVariant', 0], ['00000000000000000000000000000000', 'getVersion', null], ['00000000000000000000000000000000', 'isNil', true], diff --git a/tests/Nonstandard/FieldsTest.php b/tests/Nonstandard/FieldsTest.php index 5286cd7..72347f1 100644 --- a/tests/Nonstandard/FieldsTest.php +++ b/tests/Nonstandard/FieldsTest.php @@ -41,12 +41,14 @@ class FieldsTest extends TestCase public function fieldGetterMethodProvider(): array { return [ + ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeq', '0b21'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeqHiAndReserved', '0b'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getClockSeqLow', '21'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getNode', '0800200c9a66'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeHiAndVersion', '91e1'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimeMid', 'c57d'], + ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getVariant', Uuid::RESERVED_NCS], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'getVersion', null], ['ff6f8cb0-c57d-91e1-0b21-0800200c9a66', 'isNil', false], diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index e875b4b..119e512 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -105,52 +105,62 @@ class FieldsTest extends TestCase public function fieldGetterMethodProvider(): array { return [ + ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeq', '1b21'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqHiAndReserved', '9b'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getClockSeqLow', '21'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getNode', '0800200c9a66'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeHiAndVersion', '11e1'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimeMid', 'c57d'], + ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVariant', 2], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'getVersion', 1], ['ff6f8cb0-c57d-11e1-9b21-0800200c9a66', 'isNil', false], + ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeq', '2b21'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqHiAndReserved', 'ab'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getClockSeqLow', '21'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getNode', '0800200c9a66'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeHiAndVersion', '41e1'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimeMid', 'c57d'], + ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVariant', 2], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'getVersion', 4], ['ff6f8cb0-c57d-41e1-ab21-0800200c9a66', 'isNil', false], + ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeq', '3b21'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqHiAndReserved', 'bb'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getClockSeqLow', '21'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getNode', '0800200c9a66'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeHiAndVersion', '31e1'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimeMid', 'c57d'], + ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVariant', 2], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'getVersion', 3], ['ff6f8cb0-c57d-31e1-bb21-0800200c9a66', 'isNil', false], + ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeq', '0b21'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqHiAndReserved', '8b'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getClockSeqLow', '21'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getNode', '0800200c9a66'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeHiAndVersion', '51e1'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeLow', 'ff6f8cb0'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimeMid', 'c57d'], + ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getTimestamp', '1e1c57dff6f8cb0'], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVariant', 2], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'getVersion', 5], ['ff6f8cb0-c57d-51e1-8b21-0800200c9a66', 'isNil', false], + ['00000000-0000-0000-0000-000000000000', 'getClockSeq', '0000'], ['00000000-0000-0000-0000-000000000000', 'getClockSeqHiAndReserved', '00'], ['00000000-0000-0000-0000-000000000000', 'getClockSeqLow', '00'], ['00000000-0000-0000-0000-000000000000', 'getNode', '000000000000'], ['00000000-0000-0000-0000-000000000000', 'getTimeHiAndVersion', '0000'], ['00000000-0000-0000-0000-000000000000', 'getTimeLow', '00000000'], ['00000000-0000-0000-0000-000000000000', 'getTimeMid', '0000'], + ['00000000-0000-0000-0000-000000000000', 'getTimestamp', '000000000000000'], ['00000000-0000-0000-0000-000000000000', 'getVariant', 0], ['00000000-0000-0000-0000-000000000000', 'getVersion', null], ['00000000-0000-0000-0000-000000000000', 'isNil', true],