Why Use Timestamps
After understanding why JavaScript Date is problematic, you might wonder: are there any alternative?
The answer is: timestamps. JavaScript's number
type is the perfect data type for representing a moment in time.
What Are Timestamps?
A timestamp is a number representing milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). It's a single number that unambiguously represents a specific moment in time, anywhere in the world.
const now = Date.now(); // e.g., 1704067200000
const startOfTime = new Date("1970-01-01T00:00:00Z").getTime(); // 1704110400000
const startOfWW2 = new Date("1939-09-01T00:00:00Z").getTime();
console.log("Now", now);
console.log("Start of Time", startOfTime);
console.log("Start Of World War 2", startOfWW2);
Why Timestamps Are Superior
1. Universal and Unambiguous
Unlike Date
objects, timestamps represent the exact same moment in time regardless of where your code runs.
const timestamp = 1704110400000; // 2024-01-01T12:00:00Z
// It's just a number, it will always be the same everywhere. Easy :)
console.log(timestamp); // Always logs: 1704110400000
2. Immutable by Nature
Numbers cannot be mutated in JavaScript, eliminating an entire class of bugs.
const original = Date.now();
const modified = original + 60 * 60 * 1000; // Add 1 hour
// Original is unchanged
console.log(original); // Still the original value
console.log(modified); // New value, original untouched
3. Perfect Serialization
Timestamps serialize and deserialize perfectly with JSON, databases, and APIs.
const data = {
createdAt: Date.now(),
scheduledFor: new Date("2024-12-31T23:59:59Z").getTime(),
updatedAt: Date.now(),
};
const json = JSON.stringify(data);
const parsed = JSON.parse(json);
// All values are intact
console.log(typeof parsed.createdAt); // "number"
4. Zero Memory Overhead
Timestamps are fast and lightweight primitive values with no object overhead on the JavaScript heap.
// Efficient memory usage
// Time timestamp creation
const timestampStart = performance.now();
for (let i = 0; i < 1000000; i++) {
Date.now();
}
const timestampEnd = performance.now();
const timestampTime = timestampEnd - timestampStart;
// Time Date object creation
const dateStart = performance.now();
for (let i = 0; i < 1000000; i++) {
new Date();
}
const dateEnd = performance.now();
const dateTime = dateEnd - dateStart;
console.log(`Timestamp loop: ${timestampTime.toFixed(2)}ms`);
console.log(`Date object loop: ${dateTime.toFixed(2)}ms`);
5. Mathematical Operations
You can perform arithmetic directly on timestamps without special functions.
const start = Date.now();
const oneHour = 60 * 60 * 1000;
const end = start + oneHour;
const duration = end - start; // Always 3,600,000 milliseconds
const isAfter = end > start; // Always true
console.log("duration", duration);
console.log("is after", isAfter);
What Timestamps Are Lacking
Even though timestamps are the best storage format, they are not the best presentation or manipulation format for humans.
1. Human-Readable Calendar Values
Humans think in calendar units: "March 14 at 3 PM", not 1710436800000
. Whenever you need to display a date or accept input from a human, convert the raw timestamp with datezone's formatting helpers.
import { format } from "datezone";
const timestamp = 1710436800000;
const formatted = format(timestamp, "YYYY-mm-dd z", {
timeZone: "America/New_York",
});
console.log(formatted); // 2024-20-14 GMT-4
2. No Built-in DST Awareness
Simple timestamp math works for seconds, minutes and hours, but beyond that you will run into issues with Daylight Saving Time (DST). Adding 24 × 60 × 60 × 1000 milliseconds will usually move you one day forward, but not across a DST transitions.
// Demonstrates how naive duration calculations ignore the "skipped" hour when Daylight Saving Time starts in New York (America/New_York).
// 1:59 AM EST (UTC-5) — just before the clocks spring forward
const before = new Date("2024-03-10T01:59:00-05:00");
// 3:00 AM EDT (UTC-4) — the next valid local time after the DST jump
const after = new Date("2024-03-10T03:00:00-04:00");
// How many minutes does JavaScript think have passed?
const diffMinutes = (after.getTime() - before.getTime()) / 60_000;
console.log("diffMinutes", diffMinutes); // 👉 1 minute (!)
Learn more about why DST makes date math tricky in: How DST Works.
3. Higher-Level Calendar Operations
Operations such as "add one month", "start of week", or "is the date a weekend" are calendar concepts and subjective to where the user is located. datezone
offers a timezone-aware API on top of timestamps to cover all of these cases without sacrificing the benefits you gained from using numbers.
Datezone is designed as a thin layer above timestamps: use raw numbers for and performance, then use datezone whenever you have to think 'Calendar' like a human.
Summary
Timestamps are the ideal way to handle dates and times in JavaScript applications. They're simple, efficient, predictable, and work seamlessly across environments.
Key benefits: Timestamps eliminate timezone ambiguity, serialization issues, mutation bugs, and testing problems while providing better performance and simpler code.
Next, learn about how DST affects your applications and why timezone-aware date arithmetic is needed.