Skip to content

๐Ÿ•’ Time & Timezones in Software Development โ€” Why They Matter

As a software developer or automation specialist, you know this truth:
Time and timezones can make or break your system!

I recently faced this first-hand while building an attendance app.
I began with SQLite (no timezone-aware datetime support) and later migrated to PostgreSQL (timezone-aware).

But thenโ€ฆ โš  UTC showed up in my web UI because Python wasn't serializing timezone data correctly.
When querying โ€œtodayโ€™s records,โ€ date truncation missed some entries due to timezone mismatches.

In todayโ€™s world, we develop locally (e.g., India ๐Ÿ‡ฎ๐Ÿ‡ณ) but deploy on cloud servers across the globe ๐ŸŒ.
That difference in system time vs. local time can seriously hurt data accuracy and user experience.

1๏ธโƒฃ What is a Timezone?

A timezone is basically an offset from UTC (Coordinated Universal Time โ€” the modern replacement for GMT).
Think of UTC as the "world clock" โ€” it never changes with seasons or geography.

Examples: - ๐Ÿ‡ฎ๐Ÿ‡ณ India โ†’ UTC+05:30 (IST) - ๐Ÿ‡บ๐Ÿ‡ธ New York โ†’
- UTC-05:00 (EST) in winter
- UTC-04:00 (EDT) in summer - ๐Ÿ‡ฏ๐Ÿ‡ต Tokyo โ†’ UTC+09:00 (JST)


2๏ธโƒฃ Why are Timezones Tricky?

  1. Offset changes
    Some countries adjust time twice a year (Daylight Saving Time).

  2. Historical changes
    Governments sometimes change timezone rules.

  3. Local naming vs offsets

  4. Asia/Kolkata is different from just UTC+05:30
  5. The named timezone also carries future and past DST rules, not just the offset.

๐Ÿ“… Common DateTime Formats (Windows/Linux)

Below are common ways date and time are represented across systems and standards.

Format Type Example Notes
UTC 2025-08-16 08:30:00 UTC Global reference time
IST 2025-08-16 14:00:00 IST UTC+05:30
ISO 8601 2025-08-16T14:00:00+05:30 Standard for APIs
ISO 8601 (UTC) 2025-08-16T08:30:00Z Z = UTC
Epoch 1765925400 Seconds since 1970 UTC
RFC 2822 Sat, 16 Aug 2025 14:00:00 +0530 Used in HTTP/Email headers
Windows Local 8/16/2025 2:00:00 PM Regional format dependent
Linux Local Sat Aug 16 14:00:00 IST 2025 Depends on date command configuration

๐Ÿง Linux Timezone Basics

  • System timezone affects displayed local time (not UTC itself).
  • Stored in /etc/localtime (symlink to a file in /usr/share/zoneinfo).

๐Ÿ“Œ Common Commands

Command Purpose Example Output
date Show current date & time in local timezone Sat Aug 16 14:00:00 IST 2025
date -u Show current UTC time Sat Aug 16 08:30:00 UTC 2025
timedatectl View system time, UTC, and timezone info Local time: ... \n Time zone: Asia/Kolkata
timedatectl list-timezones List available timezones Asia/Kolkata, America/New_York
sudo timedatectl set-timezone <Zone> Change timezone sudo timedatectl set-timezone Asia/Kolkata
hwclock Show hardware clock (BIOS/RTC) 2025-08-16 14:00:10.123456+05:30

๐Ÿ“‚ Timezone Files

  • /etc/localtime โ†’ current timezone file (binary)
  • /usr/share/zoneinfo/ โ†’ all timezone definitions

๐ŸชŸ Windows Timezone Basics

  • Windows stores timezone info in the Registry
    (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation).
  • System timezone affects local time display; UTC remains the reference internally.

๐Ÿ“Œ Common Commands

Command Purpose Example Output
time View/set current system time The current time is: 14:00:00
date View/set current system date The current date is: Sat 08/16/2025
tzutil /g Show current timezone India Standard Time
tzutil /l List all available timezones Pacific Standard Time, UTC, ...
tzutil /s "<Time Zone Name>" Set system timezone tzutil /s "India Standard Time"
Get-TimeZone (PowerShell) Get current timezone Id: India Standard Time
Set-TimeZone -Id "<Id>" (PowerShell) Set timezone Set-TimeZone -Id "UTC"

๐Ÿ“ Notes

  • Control Panel โ†’ Date & Time โ†’ Change time zone can also be used.
  • Windows timezone names differ from Linux (Asia/Kolkata in Linux is "India Standard Time" in Windows).
  • Always check for Daylight Saving Time rules in tzutil /l.

๐Ÿ Python DateTime Basics

1๏ธโƒฃ Modules

  • datetime โ†’ Main date/time handling
  • zoneinfo โ†’ Timezone support (Python 3.9+)
  • timedelta โ†’ Time differences and arithmetic
  • time

Getting Current Time

from datetime import datetime
from zoneinfo import ZoneInfo
import time
# Local time (system timezone)
now_local = datetime.now()
print(now_local)

# UTC time
now_utc = datetime.utcnow()  # naive UTC
now_utc_aware = datetime.now(tz=ZoneInfo("UTC"))  # aware UTC
print(now_utc_aware)

## Epoch (Unix Timestamp)

time.time()                       # float seconds since epoch
int(time.time())                  # integer seconds
datetime.now(timezone.utc).timestamp()  # from datetime

## Get Current Time in ISO 8601

datetime.now(timezone.utc).isoformat()

## Convert Timezone
dt_utc = datetime.now(timezone.utc)
dt_ist = dt_utc.astimezone(ZoneInfo("Asia/Kolkata"))

## Replace Timezone (without changing the clock)
dt = datetime(2025, 8, 16, 14, 0, 0)
dt_with_tz = dt.replace(tzinfo=ZoneInfo("Asia/Kolkata"))

## Parse from String
# Format must match exactly
datetime.strptime("2025-08-16 14:00:00", "%Y-%m-%d %H:%M:%S")

## Parse from Epoch
datetime.fromtimestamp(1765925400, tz=timezone.utc)      # in UTC
datetime.fromtimestamp(1765925400, tz=ZoneInfo("Asia/Kolkata"))  # i

## Add Days / Hours / Seconds
now = datetime.now()
now + timedelta(days=1)           # Add 1 day
now + timedelta(hours=2)          # Add 2 hours
now + timedelta(seconds=30)       # Add 30 seconds

## Get Only Date or Time
dt = datetime.now()
dt.date()     # Returns date object: 2025-08-16
dt.time()     # Returns time object: 14:00:00

๐Ÿ—„ SQLModel / SQLAlchemy โ€” Time & Timezone Awareness


1๏ธโƒฃ Timezone Awareness in SQLAlchemy

SQLAlchemy provides DateTime(timezone=True) for timezone-aware datetime columns.

from datetime import datetime, timezone
from sqlmodel import SQLModel, Field
from typing import Annotated

class Event(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc), sa_column_kwargs={"timezone": True})

2๏ธโƒฃ Example with SQLAlchemy Core

from sqlalchemy import Column, DateTime
from sqlalchemy.sql import func

created_at = Column(DateTime(timezone=True), server_default=func.now())

3๏ธโƒฃ Enforcing UTC in SQLModel using Annotated

from datetime import datetime, timezone
from sqlmodel import SQLModel, Field
from typing import Annotated

def ensure_utc(dt: datetime) -> datetime:
    """Force datetime to be UTC-aware."""
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    else:
        dt = dt.astimezone(timezone.utc)
    return dt

UTCDateTime = Annotated[datetime, ensure_utc]

class Log(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    timestamp: UTCDateTime = Field(default_factory=lambda: datetime.now(timezone.utc), sa_column_kwargs={"timezone": True})

๐Ÿผ Pandas DateTime, Epoch, and Timezone Basics


1๏ธโƒฃ Epoch in Pandas

  • Epoch time = seconds since 1970-01-01 00:00:00 UTC.
  • Pandas supports:
  • Seconds โ†’ unit='s'
  • Milliseconds โ†’ unit='ms'
  • Microseconds โ†’ unit='us'
  • Nanoseconds โ†’ default for Timestamp
import pandas as pd

# From epoch seconds
pd.to_datetime(1692172800, unit='s', utc=True)

# From epoch milliseconds
pd.to_datetime(1692172800000, unit='ms', utc=True)

# From epoch microseconds
pd.to_datetime(1692172800000000, unit='us', utc=True)

2๏ธโƒฃ Relation with Python datetime

pandas.Timestamp is a subclass of Pythonโ€™s datetime.datetime but with nanosecond precision. Fully compatible with Python datetime functions.

ts = pd.Timestamp.now(tz="UTC")
isinstance(ts, datetime)  # True

3๏ธโƒฃ NumPy and Pandas DateTime

Under the hood, Pandas often uses NumPyโ€™s datetime64 for efficiency.

NumPy stores datetimes as integer nanoseconds from epoch.

Example:

import numpy as np
np.datetime64('2025-08-16T14:00:00Z')
np.datetime64(1692172800000, 'ms')  # from milliseconds

4๏ธโƒฃ Current Time in Pandas

pd.Timestamp.now()               # Local time
pd.Timestamp.utcnow()            # Naive UTC
pd.Timestamp.now(tz="UTC")       # Aware UTC

5๏ธโƒฃ Convert Between Timezones

ts = pd.Timestamp.now(tz="UTC")
ts.tz_convert("Asia/Kolkata")

6๏ธโƒฃ Parse from String / Python datetime

pd.to_datetime("2025-08-16 14:00:00", utc=True)
pd.to_datetime(datetime.now(), utc=True)

8๏ธโƒฃ Add / Subtract Time

ts + pd.Timedelta(days=1)
ts + pd.Timedelta(hours=2)
ts - pd.Timedelta(seconds=30)

๐Ÿ•’ NumPy Date & Time Handling

NumPyโ€™s datetime64 is not timezone-aware โ€” all datetime values are stored in a fixed, absolute scale based on UTC, but without any explicit timezone information attached Benefit โ†’ Because itโ€™s timezone-naive, operations like subtraction, sorting, and broadcasting are faster and more memory-efficient โ€” but you must handle local time conversion yourself.

  1. Datetime Types

    numpy.datetime64 โ†’ Represents a specific date/time.

    numpy.timedelta64 โ†’ Represents a time difference (duration).

    Supports different precisions: year (Y), month (M), day (D), hour (h), minute (m), second (s), millisecond (ms), microsecond (us), nanosecond (ns).

  2. Key Functions ```python

    Create datetime objects

    import numpy as np np.datetime64('2025-08-16') np.datetime64('2025-08-16T15:30')

    Current date/time

    np.datetime64('now')

    Date range generation

    np.arange('2025-08-01', '2025-08-05', dtype='datetime64[D]')

    Time differences

    np.datetime64('2025-08-16') - np.datetime64('2025-08-10')

    โ†’ numpy.timedelta64(6,'D')

    Vectorized datetime operations

    dates = np.array(['2025-08-16', '2025-08-20'], dtype='datetime64') mask = dates > np.datetime64('2025-08-17')

    array([False, True])

    ```

  3. Benefits

    โœ… Vectorized operations โ†’ Work on entire arrays of dates at once (fast, memory-efficient).

    โœ… Multiple precisions โ†’ From years down to nanoseconds.

    โœ… Simple arithmetic โ†’ Easy difference, addition, and comparison.

    โœ… Interoperability โ†’ Works well with Pandas time series.

    โœ… Lightweight โ†’ Less overhead than Python datetime objects for large datasets.

๐Ÿ“Œ Real-World Use Cases Where Timezone Awareness Is Crucial

  • ๐Ÿ“… Scheduling & calendar events across regions
  • ๐Ÿ•“ Attendance & time-tracking for remote teams
  • ๐Ÿ—‚ Logging & audit trails in global systems
  • ๐Ÿ’ฐ Financial transactions for compliance & reconciliation
  • ๐Ÿ”„ Data synchronization between countries
  • ๐Ÿ“Š User activity tracking with local timestamps
  • โš™ Automation workflows running in user-local time
  • โณ Daylight Saving Time (DST) handling
  • ๐Ÿ“ก Cross-system communication with consistent time references

๐Ÿ›  Lessons Learned from My Journey

โœ… Store in UTC โ€” Always keep a single, reliable reference point

โœ… Display in local time โ€” Convert UTC โ†’ userโ€™s timezone for UI

โœ… In storage โ€” Prefer native datetime types (with timezone awareness)

โœ… In APIs & inter-system exchange โ€” Use ISO 8601 for human-readability or Epoch for compactness โ€” but be consistent

โœ… For high-performance pipelines (like Kafka or binary protocols) โ€” Use Epoch to minimize serialization/deserialization cost

โœ… Convert before comparing โ€” Local time โ†’ UTC for filters & sorting

โœ… Preserve timezone info โ€” During serialization/deserialization

โœ… Use reliable libraries โ€” For conversion & DST handling

โœ… Test edge cases โ€” DST shifts, leap years, timezone borders

โœ… Document assumptions โ€” For team & stakeholders

โœ… Stay disciplined โ€” Especially when developing locally & deploying remotely

โœ… Stay updated โ€” Timezones are political & constantly changing (IANA DB ๐Ÿ“…)


๐Ÿ’ก Final Thought:
Handling timezones isnโ€™t a minor detail โ€” itโ€™s the backbone of reliable global applications.
Ignore it, and you risk confusing users, corrupting data, and introducing subtle bugs.