Why REST APIs Use Unix Time (and How to Convert It in Any Language)
Published apiunix-timestampjavascriptpythonbackend
You’re integrating Stripe’s API and the created field returns 1712700000. Over on GitHub, created_at gives you "2024-04-09T20:00:00Z". Slack’s ts field hands you "1712700000.123456" — a string, with a decimal point. Three major APIs, three different timestamp formats, all pointing to the same moment in time.
Why do so many APIs default to Unix time? And when you’re staring at a raw integer or a float string at 11pm debugging a webhook, what’s the fastest way to convert it? This article answers both.
Why APIs Use Unix Time
Unix timestamps are not just a convention — they solve four concrete problems that every distributed system eventually runs into.
1. Timezone neutrality
1712700000 is the same moment everywhere on Earth. An ISO string like "2024-04-09T20:00:00" without a timezone offset is meaningless — is that UTC? Pacific? The server’s local time? Stripe processes payments across 47 countries. Storing or transmitting ambiguous local times would be a billing disaster. A single integer sidesteps the problem entirely.
2. Arithmetic simplicity
“Did this webhook arrive in the last 24 hours?” In Unix time that’s one line:
now - ts < 86400
Try expressing that cleanly with ISO strings. You’d need to parse both strings into date objects, subtract, and handle edge cases around daylight saving transitions. With integers, the math is just math.
3. No parsing ambiguity
Is 04/09/2024 April 9th or September 4th? Depends on the locale. Does 2024-04-09T20:00:00 include a timezone? Depends on the API. Unix timestamps have exactly one representation: a non-negative integer (or float). There is no format variant, no AM/PM, no separator inconsistency.
4. Compact representation
A Unix timestamp is 10 digits. An ISO 8601 datetime is 24 characters. At scale — millions of API calls, billions of database rows — the difference adds up. Payment processors and log aggregators care about this.
What the real APIs actually do
- Stripe:
created,current_period_end, andtrial_endall return integer seconds since epoch. Every timestamp in the Stripe API is Unix time. - GitHub: uses ISO 8601 strings with explicit
Zsuffix (created_at: "2024-04-09T20:00:00Z"). GitHub is the notable exception — most data and payment APIs favour integers. - Slack: uses a string float —
"1712700000.123456"— where the integer part is seconds and the decimal is microseconds. This is Slack’s own format, not standard Unix time, and it trips up developers constantly because you have to parse a string before you can do any arithmetic. - Twilio:
date_createdreturns integer seconds since epoch, consistent with Stripe.
The pattern: APIs dealing with money, events, or high-frequency data tend to use Unix time. Collaboration tools with human-readable audit trails (GitHub, Jira) lean toward ISO 8601.
Converting Unix Timestamps in JavaScript, Python, and Go
JavaScript
JavaScript’s Date constructor expects milliseconds, but most APIs return seconds. The multiply-by-1000 step is the most common source of off-by-1000x bugs.
// Stripe returns seconds — multiply by 1000 for Date
const stripeTs = 1712700000;
const date = new Date(stripeTs * 1000);
console.log(date.toISOString()); // "2024-04-09T20:00:00.000Z"
// Slack returns a string float — parse carefully
const slackTs = "1712700000.123456";
const slackDate = new Date(parseFloat(slackTs) * 1000);
console.log(slackDate.toISOString()); // "2024-04-09T20:00:00.123Z"
// Convert current time to Unix seconds (for sending to APIs)
const nowSeconds = Math.floor(Date.now() / 1000);
Note: parseFloat on Slack’s string is safe here because you’re immediately multiplying before passing to Date. Do not use the raw string in any other arithmetic context without parsing first.
Python
Python’s datetime.fromtimestamp() accepts a float, so it handles both Stripe’s integers and Slack’s string floats after a single cast. Always pass tz=timezone.utc — omitting it silently uses the server’s local timezone, which will produce wrong results on any machine not set to UTC.
from datetime import datetime, timezone
# Stripe: integer seconds
stripe_ts = 1712700000
dt = datetime.fromtimestamp(stripe_ts, tz=timezone.utc)
print(dt.isoformat()) # "2024-04-09T20:00:00+00:00"
# Slack: string float
slack_ts = "1712700000.123456"
dt_slack = datetime.fromtimestamp(float(slack_ts), tz=timezone.utc)
print(dt_slack.isoformat()) # "2024-04-09T20:00:00.123456+00:00"
# Convert current time to Unix seconds
import time
now_seconds = int(time.time())
Go
Go’s time.Unix() takes two arguments: seconds and nanoseconds. Pass 0 for the nanosecond argument when you only have second precision. Call .UTC() to make the timezone explicit in output.
import (
"fmt"
"time"
)
// Stripe: int64 seconds
stripeTs := int64(1712700000)
t := time.Unix(stripeTs, 0).UTC()
fmt.Println(t.Format(time.RFC3339)) // "2024-04-09T20:00:00Z"
// Slack: string float — parse then split into seconds and nanoseconds
// strconv.ParseFloat(slackTs, 64) gives you the seconds as a float
// Multiply fractional part by 1e9 for nanoseconds
stripeFloat := 1712700000.123456
secs := int64(stripeFloat)
nsecs := int64((stripeFloat - float64(secs)) * 1e9)
tSlack := time.Unix(secs, nsecs).UTC()
fmt.Println(tSlack.Format(time.RFC3339Nano)) // "2024-04-09T20:00:00.123456001Z"
// Current time as Unix seconds (for sending to APIs)
now := time.Now().Unix()
Quick Check: Paste It Into the Tool
When integrating a new API and you’re not sure what a timestamp value means, paste it straight into our unix timestamp converter — it handles seconds, milliseconds, and ISO strings in one shot.
When NOT to Use Unix Time
Unix timestamps are not always the right choice. ISO 8601 is actually better in three situations:
Human-readable storage. Log files, config files, and CSV exports that humans will open in a text editor are much easier to audit when dates are written as 2024-04-09T20:00:00Z rather than 1712700000. The readability gain outweighs the compactness advantage.
Preserving the original timezone offset. A calendar event created in Tokyo should store +09:00, not be silently normalised to UTC. If you store the Unix timestamp and reconstruct the time in UTC, you lose the information about where the event was originally scheduled. ISO 8601 with explicit offsets preserves this.
SQL databases. Most modern databases — PostgreSQL, MySQL 8+, SQL Server — have native TIMESTAMP WITH TIME ZONE types that handle timezone-aware storage better than bare integers. Use the database type; let the database handle conversion.
Further Reading
Try it in your browser
No setup needed — use our free Epoch Converter directly online.