← Back

Server-Side Timestamps

How to handle timestamps from browsers around the world. The key insight: there is one point in time universally, and it's UTC.

Server Time (UTC)

2026-02-03T08:11:37.249Z

This is the universal truth. Every timestamp from every timezone converts to this moment.

The Transfer Protocol Flow

1. Browser

User in New York clicks "Submit" at 2:30 PM EST

2. Transfer

Whenny creates payload with UTC timestamp + timezone context

3. Server

Receives 7:30 PM UTC and knows it originated in EST

Simulated Events from Different Timezones

These are simulated browser timestamps that arrived at the server. Each shows the same moment in time, displayed correctly for its origin timezone.

User in New York

Submitted form

31 seconds ago

UTC (stored)

2026-02-03T08:11:07.249Z

Origin timezone

America/New_York

Display (local to user)

3:11 AM EST

User in London

Updated profile

46 seconds ago

UTC (stored)

2026-02-03T08:10:52.249Z

Origin timezone

Europe/London

Display (local to user)

8:10 AM GMT

User in Tokyo

Created post

just now

UTC (stored)

2026-02-03T08:11:22.249Z

Origin timezone

Asia/Tokyo

Display (local to user)

5:11 PM GMT+9

How It Works

Browser: Send timestamp with context
// When user clicks "Submit"
const payload = createTransfer(new Date(), {
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
})

// Result: { iso: "2024-01-15T19:30:00.000Z", originZone: "America/New_York", originOffset: -300 }

fetch('/api/events', {
  method: 'POST',
  body: JSON.stringify({ timestamp: payload })
})
Server: Receive and understand
// API receives the transfer payload
const received = fromTransfer(body.timestamp)

received.date          // JavaScript Date (UTC)
received.originZone    // "America/New_York"
received.originOffset  // -300 (minutes)

// Store in database
await db.events.create({
  datetime: received.date,        // Always store UTC
  originZone: received.originZone // Remember where it came from
})
Display: Show correctly anywhere
// Show to the original user (New York)
whenny(event.datetime).inZone(event.originZone).format('{time}')
// "2:30 PM"

// Show to a user in Tokyo
whenny(event.datetime).inZone('Asia/Tokyo').format('{time}')
// "4:30 AM"

// Show to a user in London
whenny(event.datetime).inZone('Europe/London').format('{time}')
// "7:30 PM"

// All showing the same moment in time, correctly localized.

Key Insight

When a user in New York clicks a button at 2:30 PM their time, and a user in Tokyo clicks a button at 4:30 AM their time (the next day), they might be clicking at the exact same moment. UTC is how you know that. The timezone context tells you how to display it back to each user correctly.

This page was server-rendered. All formatting happened before the HTML was sent.