clock
Time abstraction port for testability and consistency
Clock is a platform primitive that abstracts time access. Instead of calling datetime.now() directly, components inject a Clock port, enabling deterministic testing and consistent time zone handling. Implementations include SystemClock for production and FixedClock for testing.
0
Ports
0
Schemas
3
Hooks
2
Events
01
Ports
Adapters Provided
- SystemClock
- FixedClock
02
Schemas
Defines
No schemas defined
Uses
No external schemas used
03
Hooks
- before_now
- after_advance
- after_set
04
Events
- TimeAdvanced v1
- TimeSet v1
05
Stories
06
Examples
class CreateTaskUseCase:
def __init__(self, repo: TaskRepository, clock: Clock) -> None:
self._repo = repo
self._clock = clock
async def execute(self, input: CreateTaskInput) -> CreateTaskOutput:
now = self._clock.now()
task = Task(id=uuid4(), created_at=now, ...)
await self._repo.add(task)
return CreateTaskOutput(task_id=task.id, created_at=now)
Use cases receive Clock as a dependency.
from datetime import datetime, UTC
from psp.platform.clock import FixedClock
def test_task_created_at():
fixed_time = datetime(2024, 1, 15, 10, 30, tzinfo=UTC)
clock = FixedClock(fixed_time)
use_case = CreateTaskUseCase(repo=InMemoryRepo(), clock=clock)
result = use_case.execute(CreateTaskInput(title="Test"))
assert result.created_at == fixed_time
Control time in tests for deterministic results.
clock = FixedClock(datetime(2024, 1, 1, tzinfo=UTC))
# Create a reminder due in 1 hour
reminder = scheduler.schedule(due_at=clock.now() + timedelta(hours=1))
# Advance time by 2 hours
clock.advance(hours=2)
# Now the reminder is overdue
assert reminder.due_at < clock.now()
Simulate time passing for expiration tests.
API Reference
This component mounts routes under /v1/clock.
View OpenAPI specification