diff --git a/src/TsidFactory.php b/src/TsidFactory.php index 06f24f4..509ebc0 100644 --- a/src/TsidFactory.php +++ b/src/TsidFactory.php @@ -39,12 +39,12 @@ final class TsidFactory implements TsidFactoryInterface private int $customEpoch; - public function __construct(int $nodeBits = self::NODE_BITS_1024, int $node = null) + public function __construct(int $nodeBits = self::NODE_BITS_1024, ?int $node = null, ?DateTimeImmutable $customDateUtc = null) { $this->nodeBits = $nodeBits; - // Number of milliseconds of 2020-01-01T00:00:00.000Z. - $dateUtc = new DateTimeImmutable('2020-01-01T00:00:00.000Z', new DateTimeZone('UTC')); + // Number of milliseconds of 2020-01-01T00:00:00.000Z or custom date time. + $dateUtc = $customDateUtc ?: new DateTimeImmutable('2020-01-01T00:00:00.000Z', new DateTimeZone('UTC')); $this->customEpoch = (int)substr($dateUtc->format('Uu'), 0, 13); // setup constants that depend on node bits diff --git a/tests/TsidFactoryTest.php b/tests/TsidFactoryTest.php index 7c4339c..e729093 100644 --- a/tests/TsidFactoryTest.php +++ b/tests/TsidFactoryTest.php @@ -2,6 +2,8 @@ namespace Odan\Tsid\Test; +use DateTimeImmutable; +use DateTimeZone; use Odan\Tsid\Tsid; use Odan\Tsid\TsidFactory; use PDO; @@ -80,4 +82,24 @@ public function testSqlLite(): void ]; $this->assertSame($expected, $user); } + + public function testCustomDateUtc(): void + { + $customEpoch = new DateTimeImmutable('2026-01-01T00:00:00.000Z', new DateTimeZone('UTC')); + + $factoryWithCustomEpoch = new TsidFactory(TsidFactory::NODE_BITS_1024, null, $customEpoch); + $factoryWithDefaultEpoch = new TsidFactory(TsidFactory::NODE_BITS_1024); + + $tsidCustom = $factoryWithCustomEpoch->generate(); + $tsidDefault = $factoryWithDefaultEpoch->generate(); + + // The custom epoch is later than the default epoch, so TSIDs generated + // with the custom epoch will have a smaller time component (fewer milliseconds since epoch). + // This means the custom epoch TSID should be smaller than the default epoch TSID. + $this->assertLessThan($tsidDefault->toInt(), $tsidCustom->toInt()); + + // Verify both TSIDs are valid 13-character strings + $this->assertSame(13, strlen($tsidCustom->toString())); + $this->assertSame(13, strlen($tsidDefault->toString())); + } }