DEV Community

Mubeen Khan
Mubeen Khan

Posted on

10 digits or 13? The timestamp bug that sends your dates to the year 56,189

Every API you have ever used stores time as one number: the seconds since January 1, 1970. Databases do it, JWT tokens do it, log files do it. The number is timezone-free and sortable, which is why everyone uses it. And then one day your UI shows a date in the year 56,189, and you spend an hour looking for a bug that is exactly one multiplication away.

The bug is units. A Unix timestamp in seconds has 10 digits: 1700000000. A JavaScript timestamp in milliseconds has 13 digits: 1700000000000. JavaScript's Date.now() returns milliseconds. Most APIs return seconds. Feed a millisecond value into code that expects seconds and new Date(1700000000000 * 1000) lands tens of thousands of years in the future. Feed a seconds value into code that expects milliseconds and new Date(1700000000) lands in January 1970, three weeks after the epoch.

The fix is boring, which is why it works. Count the digits before you convert. Ten digits: seconds, multiply by 1000 for JavaScript. Thirteen digits: milliseconds, use as-is. Sixteen digits: microseconds, divide by 1000. Nineteen digits: nanoseconds, divide by one million. If you write a helper, make it do the counting:

function toMilliseconds(value) {
  const n = Number(value);
  const digits = String(Math.trunc(Math.abs(n))).length;
  if (digits <= 10) return n * 1000;
  if (digits <= 13) return n;
  if (digits <= 16) return n / 1000;
  return n / 1e6;
}

const date = new Date(toMilliseconds(1700000000));
console.log(date.toISOString()); // 2023-11-14T22:13:20.000Z
Enter fullscreen mode Exit fullscreen mode

Two more things that save debugging time. First, always convert through UTC and format for display last: a timestamp that "looks wrong" is usually a timezone mismatch, not a wrong value. Second, when a log file hands you a whole column of timestamps, convert them as a batch instead of one by one; the pattern in a batch (a whole column off by exactly 1000x) tells you the unit mistake instantly.

If you want to check a value without writing code, I built a free converter that handles this: it auto-detects seconds, milliseconds, microseconds and nanoseconds, shows the date in UTC, ISO 8601, your local time and a dozen timezones, and converts whole lists at once. It runs entirely in your browser, so production log values never leave your machine: Unix Timestamp Converter at https://www.theutilityhub.online/tools/unix-timestamp-converter

The rule to remember: count the digits, convert through UTC, and never trust a date in the year 56,189.

Top comments (0)