In modern web development, time is one of the most frequent sources of bugs. A user in Tokyo creates an order, the server is in Virginia, and the database is in Frankfurt. Without a strict protocol, a simple "Order Date" can morph into three different values. To build a scalable system, we must establish a "Single Source of Truth" for time data.

The Golden Rule: UTC for Transport, Local for Display

The industry standard for API communication is the Unix Timestamp (specifically, the 13-digit millisecond precision timestamp). Timestamps are timezone-agnostic integers representing an absolute moment in time.

Frontend to Backend

The frontend should send timestamps (e.g., 1779723000000). This removes ambiguity about string formats (ISO 8601 vs. others) and browser time zone settings.

const orderDate = new Date('2026-05-20T10:30:00+09:00');
const timestamp = orderDate.getTime(); // 1779723000000

fetch('/api/orders', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ orderDate: timestamp })
});

Backend to Frontend

The backend should return timestamps. The frontend is then responsible for converting this integer into a human-readable string based on the user's browser settings.

{
    "orderId": "ORD-2026-001",
    "orderDate": 1779723000000,
    "status": "confirmed"
}
// Frontend displays in user's local time
const date = new Date(response.orderDate);
console.log(date.toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
}));

Handling "Date-Only" Logic

A specific challenge arises when the business requirement is "Date Only" (e.g., selecting a delivery day). If a user selects "May 20th" on their calendar, the frontend might generate a timestamp for May 20th, 00:00:00 in their local time.

If the backend blindly saves this timestamp, it introduces "time noise." A user in New York and a user in Beijing selecting the same calendar day will generate timestamps 12 hours apart.

The Problem

// User in New York (UTC-5)
const nyDate = new Date('2026-05-20T00:00:00-05:00');
console.log(nyDate.getTime()); // 1779480000000

// User in Beijing (UTC+8)
const bjDate = new Date('2026-05-20T00:00:00+08:00');
console.log(bjDate.getTime()); // 1779436800000

// Same calendar day, different timestamps!

The Backend Sanitization Layer

The backend must act as a sanitizer. It should not trust the exact millisecond sent by the client for date-based logic. Instead, implement a normalization step:

  1. Receive the timestamp from the client.
  2. Convert it to a date string using the business's target time zone (e.g., Asia/Shanghai).
  3. Discard the time component entirely.
  4. Store the clean YYYY-MM-DD string (or UTC midnight) in the database.

Node.js Example

function sanitizeDateForStorage(timestamp, timeZone = 'Asia/Shanghai') {
    // Convert timestamp to date string in target timezone
    const dateObj = new Date(timestamp);
    const dateStr = dateObj.toLocaleDateString('en-CA', {
        timeZone: timeZone,
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
    });
    
    // dateStr is now "2026-05-20" - clean, no time component
    return dateStr;
}

// Usage
const clientTimestamp = 1779480000000; // From New York user
const cleanDate = sanitizeDateForStorage(clientTimestamp);
console.log(cleanDate); // "2026-05-20"

Python Example

from datetime import datetime
import pytz

def sanitize_date_for_storage(timestamp_ms, timezone_str='Asia/Shanghai'):
    # Convert milliseconds to datetime
    dt_utc = datetime.utcfromtimestamp(timestamp_ms / 1000)
    dt_utc = dt_utc.replace(tzinfo=pytz.UTC)
    
    # Convert to target timezone
    tz = pytz.timezone(timezone_str)
    dt_local = dt_utc.astimezone(tz)
    
    # Return date string without time component
    return dt_local.strftime('%Y-%m-%d')

# Usage
client_timestamp = 1779480000000
clean_date = sanitize_date_for_storage(client_timestamp)
print(clean_date)  # "2026-05-20"

Why Not Just Use Strings?

While passing ISO date strings (e.g., "2026-05-20") is readable, it is prone to parsing errors. Different browsers and libraries (like Moment.js or date-fns) may interpret a bare date string differently—some assume UTC, others assume local time.

// Different browsers may interpret this differently:
const date1 = new Date('2026-05-20');
// Some: 2026-05-20T00:00:00Z (UTC)
// Others: 2026-05-20T00:00:00+08:00 (Local)

The timestamp approach, combined with strict backend normalization, creates a "dumb pipe" for data transport and a "smart processor" on the server, ensuring data integrity across the entire stack.

Best Practices Summary

For Frontend

  • Always send timestamps (milliseconds) to the backend
  • Use Date.getTime() or Date.now() for current timestamps
  • Only convert to local strings for display purposes

For Backend

  • Never trust client-side date formatting for business logic
  • Normalize all date-based inputs using explicit time zones
  • Store "date-only" fields as YYYY-MM-DD strings or UTC midnight
  • Document your time zone conventions clearly

For Database

  • Use appropriate data types: DATE for calendar dates, TIMESTAMPTZ for absolute moments
  • Always specify time zones in your database connections
  • Consider storing business date separately from timestamp for reporting

Frequently Asked Questions

Should I use seconds or milliseconds for timestamps?

Milliseconds (13 digits) are preferred for JavaScript/web applications because Date.now() returns milliseconds. Seconds (10 digits) work for Unix command-line tools and some APIs.

What if my frontend users span multiple time zones?

Send timestamps from the frontend—they are timezone-agnostic. Let the backend normalize based on the business's target timezone, not the user's timezone (unless specifically required).

How do I handle "relative" dates like "next Monday"?

Calculate these on the frontend using the user's local timezone, send the resulting timestamp to the backend, and let the backend normalize it.

Conclusion

Establishing a strict protocol for time data is essential for building scalable, bug-free web applications. The key principles are:

  1. UTC timestamps for transport - Integers are unambiguous and timezone-agnostic
  2. Local time for display only - Let each client render in their own timezone
  3. Backend sanitization - Normalize all date inputs using explicit time zones
  4. Clean storage - Store "date-only" fields without time noise

By following this protocol, you can eliminate the most common time-related bugs in your application.

For more developer tools, explore our Timestamp Converter and JSON Formatter.