How to Fix Timestamp Errors in APIs
Timestamp bugs in APIs are among the most deceptive. The application appears to work fine — data is saved, requests succeed — but dates are silently wrong. An event recorded at 3 PM shows as 8 PM. A record created today appears as created in January 1970. A scheduled job fires one hour late every spring. This guide catalogs the most common timestamp errors in APIs and gives you concrete fixes for each one.
Error: Dates Showing as January 1, 1970
The 'January 1, 1970' error is one of the most common and also one of the easiest to diagnose. It occurs when a timestamp value of 0 or near-0 is passed to a date conversion function, causing the result to be the Unix epoch — the zero point of Unix time. Cause 1: Null or undefined values being coerced to 0. In JavaScript, parseInt(null) is NaN, but new Date(null) returns January 1, 1970 00:00:00 UTC because null is coerced to 0. Similarly in some databases, NULL values in timestamp columns may display as epoch when coerced. Cause 2: Uninitialized default values. A timestamp column with a DEFAULT 0 will appear as January 1, 1970 for any row inserted without explicitly setting the timestamp. Cause 3: Wrong unit — seconds passed where milliseconds are expected. The value 1715500 in seconds is January 20, 1970 — very close to epoch. If you have a 7-digit number that's converting to a date near 1970, you may have truncated a millisecond timestamp. Fix: Add validation to ensure timestamps are above a reasonable minimum threshold before displaying. In JavaScript: if (!ts || ts < 1000000000) return 'Invalid date'. Check database column defaults and change 0 defaults to NULL (and handle NULL in the application layer) or to CURRENT_TIMESTAMP. Use our converter to verify the value by pasting the raw number — if it shows 1970, the value is the problem, not the conversion code.
Error: Dates in the Far Future (Year 51,000+)
When a date shows as being tens of thousands of years in the future, the almost certain cause is a millisecond timestamp being treated as a second timestamp — or even a microsecond timestamp being treated as milliseconds. The symptom looks like this: a timestamp of 1715500800000 (milliseconds) is passed to Python's datetime.utcfromtimestamp(1715500800000). Python expects seconds, so it interprets this as 1,715,500,800,000 seconds after the epoch — which is the year 56,367. Fix: Identify the unit of the timestamp at the source. Apply the digit-count heuristic: 10 digits = seconds (current), 13 digits = milliseconds (current). Divide by 1000 if you have milliseconds and need seconds. In Python, use datetime.utcfromtimestamp(ts / 1000) for millisecond inputs. Add a unit guard: if ts > 1e12: ts = ts / 1000 normalizes both common formats to seconds. For APIs you control, document the unit explicitly in your API schema and validate incoming values against the expected range. A seconds timestamp for 2026 should be around 1.74 billion. Reject any value that is implausibly large or small.
Error: Times Off by a Fixed Number of Hours
When timestamps are consistently off by a fixed number of hours — exactly 1, 2, 5, 8, or another round number — the cause is almost always a timezone offset being applied twice, not applied, or applied incorrectly. Scenario 1: UTC stored but not converted on display. The timestamp is correctly stored in UTC but displayed without timezone conversion. A user in UTC+2 sees times that are two hours behind reality. Scenario 2: Local time stored as UTC. The server is in UTC+5. The application stores the current local server time as if it were UTC. All timestamps are 5 hours ahead of the true UTC time. Users see times that are 5 hours in the future. Scenario 3: Timezone converted twice. The application converts UTC to local time on storage AND on display, resulting in double conversion. A UTC+2 user sees times that are 4 hours ahead. Fix for Scenario 1: Convert to the user's timezone at display time using IANA timezone names. In JavaScript: use Intl.DateTimeFormat with the user's timezone preference. In Python: use zoneinfo.ZoneInfo with the IANA name. Fix for Scenario 2: Normalize all storage to UTC. Replace all calls to datetime.now() (local) with datetime.now(timezone.utc) in Python, or new Date() (which is already UTC internally) in JavaScript — but ensure you are sending the UTC value to the server, not a pre-formatted local string. Fix for Scenario 3: Audit your conversion pipeline. Timestamps should be stored as UTC integers, converted to local timezone exactly once at display time. Every step in between should pass the UTC value unchanged.
Error: Times Off by One Hour Intermittently (DST Bug)
The intermittent one-hour offset is the signature of a Daylight Saving Time bug. It occurs because a fixed offset (like -5 for EST) is used instead of a timezone-aware conversion that accounts for DST transitions. The symptom: times are correct most of the year but are off by one hour for several weeks around spring and autumn DST transitions. This is one of the hardest timestamp bugs to catch in testing because it only manifests at specific times of year. The cause is using a fixed numeric offset instead of an IANA timezone name. If you hard-code the offset -5:00 for New York, times are correct during EST (Eastern Standard Time, November to March) but wrong by one hour during EDT (Eastern Daylight Time, March to November), which is -4:00. Fix: Always use IANA timezone names (like 'America/New_York') rather than fixed offsets. Every proper timezone library knows the DST rules for every region and will apply the correct offset for any given date. In JavaScript: use Intl.DateTimeFormat with timeZone: 'America/New_York'. In Python: use ZoneInfo('America/New_York'). For APIs, never expose a fixed offset in the API contract if the intent is a specific geographic timezone. Store and transmit UTC; apply the timezone in the display layer using IANA names. To verify a DST bug, convert a timestamp from mid-summer and one from mid-winter using our Unix Timestamp Converter. If one shows the expected local time and the other is off by an hour, you have a DST issue.
Frequently Asked Questions
- Why does my API return different times in summer and winter?
- This is almost certainly a DST bug. Your code is using a fixed timezone offset (like +1 or -5) instead of a timezone-aware conversion based on IANA timezone names. In summer, the correct offset may differ from the fixed one by one hour. Fix by switching to IANA timezone names (e.g., 'Europe/London', 'America/Chicago') in your date conversion code. These automatically apply the correct DST-aware offset for any given date.
- What does 'null timestamp' look like when converted to a date?
- It depends on the language. In JavaScript, new Date(null) returns January 1, 1970 (null is coerced to 0). In Python, passing None to datetime.fromtimestamp() raises a TypeError. In SQL, NULL timestamps display as NULL (not a date). The most common symptom in JavaScript-based systems is the January 1, 1970 date for null or uninitialized timestamps. Always validate that a timestamp is non-null and within a reasonable range before converting.
- How do I prevent timestamp bugs when accepting timestamps from external clients?
- Validate inputs at the API boundary. Check that received timestamps fall within a plausible range (for example, between year 2000 and year 2100 in epoch seconds). Reject values that are clearly wrong, such as zeros, negative numbers (for future-dated applications), or values implying dates in the far future. Document in your API spec whether you expect seconds or milliseconds and enforce it with a schema validator. Use a Unix Timestamp Converter during testing to manually verify that test payloads contain the values you think they do.