Date formats worth knowing
Dates are complicated precisely because they are a domain shared between humans, machines and time zones. Some key formats:
- ISO 8601:
2026-04-26T14:30:00Z. International standard, supports time zone, sortable as a string. It is what serious APIs use. - ISO date:
2026-04-26. Date only, no time. ForDATEcolumns in SQL. - RFC 3339: a stricter subset of ISO 8601. It is what JSON Schema and many languages use.
- Unix timestamp:
1745676600. Seconds since 1970-01-01 UTC. Compact and monotonic. - Local string:
26/04/2026or04/26/2026. Good for showing the user, terrible for storing.
UTC vs time zones
The golden rule in modern applications: store everything in UTC, display in the user's time zone. If you store dates in local time, you face:
- Inconsistent conversions when the server is in UTC and the database in another zone.
- Daylight saving changes that create duplicate or non-existent hours.
- Inability to compare events across users in different zones.
For tests, this generator produces dates in UTC by default. Mix in different timezones to catch conversion bugs.
Dates in automated tests
- Don't use
new Date()in assertions. Mock the clock with libraries like Sinon, vitest'svi.useFakeTimers(), or jest mock timers. - Reproducibility. If a test depends on dates, fix a seed and a simulated "now". Otherwise tests pass or fail depending on the time of day.
- Temporal edge cases. February 29, DST changes, year transitions. Generate dates that hit those cases.
- Relative ranges. "7 days ago" should be computed from the mocked now, not the real one.
The year 2038 problem
Signed 32-bit Unix timestamps overflow on January 19, 2038 at 03:14:07 UTC. Systems
still using 32-bit time_t will have bugs that day. It is the modern
equivalent of Y2K.
If you generate dates for future tests, consider including dates past 2038 to verify that your system uses 64 bits or alternative representations (ISO 8601, BigInt). Most modern languages have already migrated, but legacy databases remain vulnerable.
Typical use cases
- Account creation dates. Plausible distribution: few old users, many recent ones. Generate up to 3-5 years ago.
- Order dates. Concentrated in business hours, peaks on certain days. Combine with the "business hours" option.
- Birth dates. Range between 80 and 18 years ago for age-validation tests.
- Logs. Uniform distribution with exact seconds.
- Expirations. Future dates with plausible durations (1-12 months).
Date bugs that show up late
Three classic bugs that only surface in production:
- Off-by-one in time zones. A user in GMT+10 sees "Monday" when your database stores it as "Sunday UTC".
- Truncation on insert. Your API receives ISO 8601 with milliseconds but the column is
TIMESTAMP(0). You lose precision. - Hardcoded format strings.
"DD/MM/YYYY"in moment.js fails with US-format data.