Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/TsidFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions tests/TsidFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Odan\Tsid\Test;

use DateTimeImmutable;
use DateTimeZone;
use Odan\Tsid\Tsid;
use Odan\Tsid\TsidFactory;
use PDO;
Expand Down Expand Up @@ -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()));
}
}