Problem solving · should-tier · asked at Amazon, Apple, Google, Meta, Microsoft, Netflix

Timezone-Naive Datetime

mediumdebugging

Problem

A session service stamps each session with an issue time and later decides whether it has expired:

from datetime import datetime, timedelta

SESSION_TTL = timedelta(hours=8)


def issue_session(user_id: str) -> dict:
    return {"user": user_id, "issued_at": datetime.utcnow().isoformat()}


def is_expired(session: dict) -> bool:
    issued = datetime.fromisoformat(session["issued_at"])
    return datetime.now() - issued > SESSION_TTL

Symptom: CI is green and the US-West deployment behaves, except that sessions there last about 15 hours instead of 8. The Mumbai deployment is the real problem: users are logged out about two and a half hours after signing in. Both regions run the same container image. Explain both numbers and fix the code.

Examples

  • In CI (containers run in UTC): a session issued at 09:00 is checked at 16:59 → not expired; at 17:01 → expired. Correct, but only because utcnow() and now() agree when the local zone is UTC.
  • Mumbai host (UTC+05:30): issued_at is 09:00 (UTC). At the same instant datetime.now() returns 14:30 local. The session already looks 5.5 hours old, so it "expires" after 8 − 5.5 = 2.5 hours of real time.
  • US-West host (UTC−07:00): at issue time now() reads 02:00, 7 hours behind the stored UTC value. The session appears to have negative age and lasts 8 + 7 = 15 hours.

Hints

  1. utcnow() and now() return the same type. Do they represent the same instant on a machine whose clock is not set to UTC?
  2. What information is missing from '2024-05-01T09:00:00' that would let a reader know which instant it refers to?
  3. Make the timestamps unambiguous first, then make comparisons refuse anything ambiguous.

Last reviewed 8 September 2026