How to Convert UTC Time to Local Time in Python ?

Introduction

Working with timestamps is a common task in data analysis, especially when handling satellite observations, logs, or global datasets. Often, timestamps are given in UTC (Coordinated Universal Time) — a standard time reference — but you may need to display or analyze them in your local time zone.

In this article, we’ll explore how to convert UTC time to local time in Python, using several practical approaches.

Convert Current UTC Time to Local Time Using zoneinfo

Using the datetime and zoneinfo Modules (Python 3.9+)

Starting from Python 3.9, the standard library includes the zoneinfo module for handling time zones without external dependencies.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from datetime import datetime
from zoneinfo import ZoneInfo

# Create a datetime object in UTC
utc_time = datetime(2025, 7, 5, 12, 0, 0, tzinfo=ZoneInfo("UTC"))
print("UTC Time:", utc_time)

# Convert to local time (e.g., US Eastern)
local_time = utc_time.astimezone(ZoneInfo("America/New_York"))
print("Local Time (US Eastern):", local_time)

Output:

1
2
UTC Time: 2025-07-05 12:00:00+00:00
  Local Time (US Eastern): 2025-07-05 08:00:00-04:00

The astimezone() method automatically adjusts for Daylight Saving Time (DST) when applicable.

Convert Current UTC Time to Local Time

You can also convert the current UTC time dynamically:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from datetime import datetime
from zoneinfo import ZoneInfo

# Current UTC time
utc_now = datetime.now(ZoneInfo("UTC"))

# Convert to local time
local_now = utc_now.astimezone(ZoneInfo("America/Los_Angeles"))

print("UTC Now:", utc_now)
print("Local Time (Los Angeles):", local_now)

This is useful for real-time applications, such as logging, monitoring systems, or data pipelines.

Convert Without Knowing the Time Zone (System Local Time)

If you just want to convert UTC to your system’s local time zone, use astimezone() with no arguments:

1
2
3
4
5
6
7
8
9
from datetime import datetime, timezone

# UTC datetime
utc_time = datetime(2025, 10, 27, 14, 0, 0, tzinfo=timezone.utc)

# Convert to local system time
local_time = utc_time.astimezone()

print("Local Time:", local_time)

Python will use your computer’s configured time zone.

Converting a Column of UTC Times in a Pandas DataFrame

When working with time series or datasets (e.g., from sensors or satellites), it’s common to convert an entire column of timestamps.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import pandas as pd

# Example DataFrame
df = pd.DataFrame({
    "utc_time": ["2025-07-05T12:00:00Z", "2025-07-05T18:00:00Z"]
})

# Convert to datetime and set timezone
df["utc_time"] = pd.to_datetime(df["utc_time"], utc=True)

# Convert to local timezone (e.g., US Eastern)
df["local_time"] = df["utc_time"].dt.tz_convert("America/New_York")

print(df)

Output:

1
2
3
utc_time                 local_time
0 2025-07-05 12:00:00+00:00 2025-07-05 08:00:00-04:00
1 2025-07-05 18:00:00+00:00 2025-07-05 14:00:00-04:00

pandas handles time zone conversions efficiently, making it ideal for large datasets.

Common Time Zone Examples

Region Zone Name Example
UTC "UTC" Global standard
Eastern US "America/New_York" EST/EDT
Pacific US "America/Los_Angeles" PST/PDT
Europe "Europe/Paris" CET/CEST
Japan "Asia/Tokyo" JST

You can find all available time zone names in the IANA time zone database.

Summary

Method Module Description
astimezone(ZoneInfo("Zone")) zoneinfo Best modern approach (Python 3.9+)
astimezone() datetime Converts to system local time
dt.tz_convert() pandas Ideal for bulk conversion in DataFrames

Key Takeaways

  • Always attach a timezone (tzinfo) before converting times.
  • Use zoneinfo (built-in) instead of older pytz for modern code.
  • Pandas provides vectorized operations for efficient timezone handling.
  • Be careful with Daylight Saving Time transitions when comparing times.

Convert UTC Time to Local Time Using Latitude and Longitude

When you only have UTC time and geographic coordinates (latitude, longitude), you can still estimate the local time in two ways:

  1. Accurately, using the timezonefinder package to determine the real time zone.
  2. Approximately, by computing the time offset from longitude (simple and fast for large datasets).

Option 1 — Using timezonefinder (Accurate Time Zone Detection)

Installation

To install the library:

1
pip install timezonefinder

Example: Convert UTC → Local Time from Coordinates

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from datetime import datetime
from zoneinfo import ZoneInfo
from timezonefinder import TimezoneFinder

# Example coordinates: Los Angeles, CA
latitude = 34.05
longitude = -118.25

# Step 1. Get timezone name
tf = TimezoneFinder()
timezone_name = tf.timezone_at(lat=latitude, lng=longitude)
print("Detected Time Zone:", timezone_name)

# Step 2. Convert UTC time to local time
utc_time = datetime(2025, 7, 5, 12, 0, 0, tzinfo=ZoneInfo("UTC"))
local_time = utc_time.astimezone(ZoneInfo(timezone_name))
print("Local Time:", local_time)

Output:

1
2
Detected Time Zone: America/Los_Angeles
Local Time: 2025-07-05 05:00:00-07:00

This approach handles Daylight Saving Time (DST) and regional time zone rules precisely.

Option 2 — Estimate Local Time from Longitude (Fast Approximation)

If you’re processing large volumes of data (e.g., millions of satellite detections) and don’t need full time zone accuracy, you can approximate local solar time using longitude:

Every 15° of longitude corresponds to 1 hour of solar time difference from UTC.

Simple Formula:

1
local_time  utc_time + (longitude / 15 hours)

This assumes the local solar noon occurs when the sun is directly overhead at that longitude — good enough for climatological studies or diurnal cycle analysis, but it won’t match local civil times exactly (no DST or political boundaries).

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import pandas as pd

# Example DataFrame
df = pd.DataFrame({
    "longitude": [-120, 0, 45],
    "pixel_date_time": pd.to_datetime([
        "2025-07-05T12:00:00Z",
        "2025-07-05T12:00:00Z",
        "2025-07-05T12:00:00Z"
    ], utc=True)
})

# Approximate local time
df["local_time"] = df["pixel_date_time"] + pd.to_timedelta(df["longitude"] / 15, unit="h")

print(df)

Output:

1
2
3
4
longitude            pixel_date_time               local_time
0       -120 2025-07-05 12:00:00+00:00 2025-07-05 04:00:00+00:00
1          0 2025-07-05 12:00:00+00:00 2025-07-05 12:00:00+00:00
2         45 2025-07-05 12:00:00+00:00 2025-07-05 15:00:00+00:00

⚠️ This does not account for DST or irregular time zones (e.g., India UTC+5:30).
But it’s excellent for approximating solar local time in global-scale analyses such as FRP diurnal cycles.

Real Example — FRP Diurnal Cycle from UTC Time and Location

Let’s now compute the Fire Radiative Power (FRP) diurnal cycle from a dataset with columns:

latitude longitude obs_date_time frp
34.1 -118.3 2025-07-05T12:00:00Z 55.2
34.1 -118.3 2025-07-05T19:00:00Z 72.4
-23.6 133.9 2025-07-05T01:00:00Z 80.5
-23.6 133.9 2025-07-05T05:00:00Z 120.3

Option 1 — Accurate Local Time (Using timezonefinder)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import pandas as pd
from datetime import datetime
from zoneinfo import ZoneInfo
from timezonefinder import TimezoneFinder

# Example dataset
df = pd.DataFrame({
    "latitude": [34.1, 34.1, -23.6, -23.6],
    "longitude": [-118.3, -118.3, 133.9, 133.9],
    "obs_date_time": [
        "2025-07-05T12:00:00Z",
        "2025-07-05T19:00:00Z",
        "2025-07-05T01:00:00Z",
        "2025-07-05T05:00:00Z"
    ],
    "frp": [55.2, 72.4, 80.5, 120.3]
})

df["obs_date_time"] = pd.to_datetime(df["obs_date_time"], utc=True)
tf = TimezoneFinder()

def get_local_time(row):
    tz_name = tf.timezone_at(lat=row["latitude"], lng=row["longitude"])
    if tz_name is None:
        tz_name = "UTC"
    return row["obs_date_time"].astimezone(ZoneInfo(tz_name))

df["local_time"] = df.apply(get_local_time, axis=1)
df["local_hour"] = df["local_time"].dt.hour

frp_diurnal = df.groupby("local_hour")["frp"].mean().reset_index()
print(frp_diurnal)

Option 2 — Approximation (Longitude-Based Offset)

For large-scale or real-time processing:

1
2
3
4
5
6
7
8
import pandas as pd

df["obs_date_time"] = pd.to_datetime(df["obs_date_time"], utc=True)
df["local_time"] = df["obs_date_time"] + pd.to_timedelta(df["longitude"] / 15, unit="h")
df["local_hour"] = df["local_time"].dt.hour

frp_diurnal = df.groupby("local_hour")["frp"].mean().reset_index()
print(frp_diurnal)

Visualize FRP Diurnal Cycle

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt

plt.figure(figsize=(8, 4))
plt.plot(frp_diurnal["local_hour"], frp_diurnal["frp"], marker="o")
plt.title("🔥 FRP Diurnal Cycle by Local Hour")
plt.xlabel("Local Hour")
plt.ylabel("Mean FRP (MW)")
plt.grid(True)
plt.show()

FRP Diurnal Cycle
FRP Diurnal Cycle

Summary

Approach Method Accuracy Speed Handles DST Use Case
timezonefinder + ZoneInfo Real time zone lookup ✅ High 🐢 Slower ✅ Yes Research & reporting
Longitude / 15 Approximation ⚠️ Medium ⚡ Very fast ❌ No Large-scale diurnal studies

References

Links Site
Python datetime — Date and Time Objects Official Python documentation
Python zoneinfo — IANA Time Zone Support Official Python documentation
pandas.to_datetime() pandas API reference
pandas.Series.dt.tz_convert() pandas API reference
timezonefinder on PyPI Python Package Index (PyPI)
timezonefinder Documentation Official documentation and usage examples
IANA Time Zone Database Source of global time zone data used by zoneinfo
Image

of