Dev Overflow Logo

Dev Overflow

Global search

Search across questions, answers, users and tags.

Loading...
save

How do I test code that depends on the current date?

clock icon

asked 1 month ago

message icon

2

eye icon

396

I have a function returning "3 days ago" style strings. The tests pass today and fail next month, which makes CI unreliable.

1export function relativeTime(date: Date) {
2 const diff = Date.now() - date.getTime()
3 // ...
4}
1export function relativeTime(date: Date) {
2 const diff = Date.now() - date.getTime()
3 // ...
4}

2 Answers

Freeze the clock. Every major test runner has fake timers now:

1beforeEach(() => {
2 vi.useFakeTimers()
3 vi.setSystemTime(new Date("2026-01-15T12:00:00Z"))
4})
5
6afterEach(() => vi.useRealTimers())
1beforeEach(() => {
2 vi.useFakeTimers()
3 vi.setSystemTime(new Date("2026-01-15T12:00:00Z"))
4})
5
6afterEach(() => vi.useRealTimers())

The alternative, which is better if you can afford the refactor, is to stop reaching for the global clock at all:

1export function relativeTime(date: Date, now: Date = new Date()) { ... }
1export function relativeTime(date: Date, now: Date = new Date()) { ... }

Now the test passes an explicit now and needs no framework magic. Injected time also makes the function easier to reason about — it becomes pure.

One gotcha with fake timers: if any code under test awaits a real promise chain, remember to advance the timers and flush microtasks, otherwise you get mysterious hangs.

1

of 1

Write your answer here

Introduce the problem and expand on what you've put in the title.

Top Questions