Back to Blog
Lesson 48 of the REST API Design: Design Your First Clean REST API course
API ArchitectureSeptember 4, 20264 min read

Handling Timezones and Dates in REST APIs: The UTC Standard

Stop guessing how to format time. Learn why ISO 8601 and UTC are the gold standard for your REST API and how to implement them to avoid common bugs.

REST APITimezonesISO 8601UTCBackend Development
Four wall clocks showing different time zones for London, New York, Tokyo, and Moscow.

Previously in this course, we covered refactoring for clean code to ensure our Task Manager API remains maintainable as it grows. In this lesson, we address one of the most frequent sources of production bugs: date and time representation.

When building distributed systems, you cannot rely on the local time of the server or the client. If your server is in New York and your client is in Tokyo, a simple "2:00 PM" becomes ambiguous—or worse, completely wrong. To build a professional API, you must standardize how you communicate time.

The UTC Requirement

The golden rule of backend development is simple: Always store and transmit time in UTC (Coordinated Universal Time).

UTC is a time standard that does not observe daylight saving time or regional offsets. By using it, you create a universal timeline. When you receive a timestamp from a client, you should immediately convert it to UTC for storage in your database. When you send data back, you send it in UTC. Let the client—the UI—handle the complexity of converting that UTC timestamp into the user's local timezone.

If you are dealing with more specialized requirements, such as handling specific calendars or time-sensitive events, you might eventually need more advanced structures, as discussed in Adding Custom Scalars: Handling Dates in GraphQL. However, for a standard REST API, UTC remains the bedrock of data integrity.

Standardizing with ISO 8601

ISO certification stickers with registration numbers on paper.

If UTC is the what, ISO 8601 is the how. ISO 8601 is the international standard for representing dates and times. It eliminates ambiguity by using a strict, machine-readable format.

The most common format for APIs is: YYYY-MM-DDTHH:mm:ss.sssZ

  • YYYY-MM-DD: The date.
  • T: A separator indicating the start of the time portion.
  • HH:mm:ss.sss: The time in 24-hour format with milliseconds.
  • Z: The "Zulu" designator, explicitly indicating that the time is in UTC.

Worked Example: Implementing Timestamps

In our Task Manager API, each task needs a createdAt and a dueDate. Let's update our resource model to enforce this format.

JAVASCRIPT
// Example: Valid Task Object
{
  "id": "task_123",
  "title": "Finish API documentation",
  "status": "pending",
  "createdAt": "2023-10-27T10:00:00.000Z",
  "dueDate": "2023-10-28T17:00:00.000Z"
}

When receiving a POST request, your backend code should parse the string and validate it. In Node.js, you would typically use Date.parse() or a library like date-fns to ensure the input follows this format:

JAVASCRIPT
// Server-side validation logic snippet
const dueDate = req.body.dueDate;

if (isNaN(Date.parse(dueDate))) {
  return res.status(400).json({ error: "Invalid date format. Use ISO 8601." });
}

Hands-on Exercise: Standardize Your Schema

  1. Open your tasks schema definition (from defining the data schema for your task manager api).
  2. Ensure that any field representing a date is explicitly stored as an ISO 8601 string.
  3. Add a validation check to your POST endpoint that rejects any date input that does not conform to the Z suffix.
  4. Verify this by sending a test request with a non-UTC string (e.g., 2023-10-27 10:00:00) and ensure your API returns a 400 Bad Request.

Common Pitfalls

  • Trusting Client Time: Never trust the client's local system clock. Always generate the createdAt timestamp on the server side using the server's UTC clock.
  • Assuming Local Time in Database: Databases often default to the server's local timezone. Always configure your database connections to operate in UTC explicitly.
  • Ignoring Timezones in Input: If a user needs to specify a local time, accept the date string, but store the offset separately or convert it to UTC immediately. Never save the local time without the offset, or you lose the reference point forever.

FAQ

Q: Should I ever store dates as Unix timestamps (integers)? A: While Unix timestamps are efficient, they are less readable in API responses and logs. ISO 8601 is generally preferred for REST APIs because it is self-documenting and natively supported by almost every JSON parser.

Q: How do I handle a user wanting to see a task in their local time? A: Send the ISO 8601 UTC string to the frontend. Modern frontend frameworks (like React or Vue) have excellent libraries (like date-fns or Day.js) that automatically convert that UTC string to the user's browser-detected timezone.

Recap

Team members presenting a project in a modern office setting with a focus on collaboration.

  • Use UTC for all time-based data to maintain a universal source of truth.
  • Use the ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ) for all API communication.
  • Validate date inputs strictly to prevent malformed data from entering your database.
  • Always perform timezone conversion on the client, never the server.

Up next: We will discuss how to keep your documentation in sync with your evolving code in Documentation Maintenance.

Similar Posts