Comment convertir l’heure UTC en heure locale en Python ?

Introduction

Travailler avec des dates et heures en UTC (timestamps) est une tâche courante en analyse de données, notamment lorsqu’on manipule des observations satellitaires, des journaux (logs) ou des jeux de données mondiaux. Souvent, les dates et heures en UTC sont exprimés en UTC (Temps Universel Coordonné) — une référence temporelle standard — mais il est souvent nécessaire de les afficher ou de les analyser dans un fuseau horaire local.

Dans cet article, nous verrons comment convertir l’heure UTC en heure locale en Python, en utilisant plusieurs approches pratiques.

Convertir l’heure UTC actuelle en heure locale avec zoneinfo

Utiliser les modules datetime et zoneinfo (Python 3.9+)

Depuis Python 3.9, la bibliothèque standard inclut le module zoneinfo pour gérer les fuseaux horaires sans dépendance externe.

Exemple :

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

# Créer un objet datetime en UTC
utc_time = datetime(2025, 7, 5, 12, 0, 0, tzinfo=ZoneInfo("UTC"))
print("Heure UTC :", utc_time)

# Convertir en heure locale (exemple : côte Est des États-Unis)
local_time = utc_time.astimezone(ZoneInfo("America/New_York"))
print("Heure locale (US Eastern) :", local_time)

Sortie :

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

La méthode astimezone() ajuste automatiquement l’heure selon l’heure d’été (DST) lorsqu’elle est applicable.

Convertir l’heure UTC actuelle dynamiquement

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

# Heure UTC actuelle
utc_now = datetime.now(ZoneInfo("UTC"))

# Conversion vers l’heure locale
local_now = utc_now.astimezone(ZoneInfo("America/Los_Angeles"))

print("UTC maintenant :", utc_now)
print("Heure locale (Los Angeles) :", local_now)

Cette approche est utile pour les applications en temps réel, comme les journaux, la surveillance de systèmes ou les chaînes de traitement de données.

Conversion sans connaître le fuseau horaire (heure locale du système)

Si vous souhaitez simplement convertir l’heure UTC en heure locale du système, utilisez astimezone() sans argument :

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

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

# Conversion en heure locale du système
local_time = utc_time.astimezone()

print("Heure locale :", local_time)

Python utilisera automatiquement le fuseau horaire configuré sur votre ordinateur.

Convertir une colonne d’heures UTC dans un DataFrame Pandas

Lorsqu’on travaille avec des séries temporelles (ex. : observations satellitaires), il est courant de convertir une colonne entière d’horodatages.

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

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

# Conversion en datetime avec fuseau horaire UTC
df["utc_time"] = pd.to_datetime(df["utc_time"], utc=True)

# Conversion vers fuseau local (exemple : US Eastern)
df["local_time"] = df["utc_time"].dt.tz_convert("America/New_York")

print(df)

Sortie :

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 gère efficacement les conversions de fuseaux horaires, ce qui le rend idéal pour de grands volumes de données.

Exemples de fuseaux horaires courants

Région Nom du fuseau horaire Exemple
UTC "UTC" Référence mondiale
Est US "America/New_York" EST/EDT
Ouest US "America/Los_Angeles" PST/PDT
Europe "Europe/Paris" CET/CEST
Japon "Asia/Tokyo" JST

La liste complète des fuseaux est disponible dans la base de données IANA.

Résumé

Méthode Module Description
astimezone(ZoneInfo("Zone")) zoneinfo Méthode moderne (Python 3.9+)
astimezone() datetime Conversion vers le fuseau horaire système
dt.tz_convert() pandas Conversion vectorisée pour DataFrames

Points clés

  • Toujours définir un fuseau horaire (tzinfo) avant la conversion.
  • Utiliser zoneinfo (intégré à Python) plutôt que pytz.
  • Pandas permet des opérations vectorisées pour de grands jeux de données.
  • Attention aux transitions d’heure d’été (DST) lors de comparaisons temporelles.

Convertir l’heure UTC en heure locale à partir de la latitude et la longitude

Quand seules les coordonnées (latitude, longitude) et l’heure en UTC sont disponibles, il est possible d’estimer l’heure locale de deux manières :

  1. Avec précision, en utilisant le module timezonefinder.
  2. En approximation, en déduisant le décalage horaire à partir de la longitude (plus rapide, mais moins précis).

Option 1 — Utiliser timezonefinder (détection précise du fuseau)

Installation

1
pip install timezonefinder

Exemple

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

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

tf = TimezoneFinder()
timezone_name = tf.timezone_at(lat=latitude, lng=longitude)
print("Fuseau détecté :", timezone_name)

utc_time = datetime(2025, 7, 5, 12, 0, 0, tzinfo=ZoneInfo("UTC"))
local_time = utc_time.astimezone(ZoneInfo(timezone_name))
print("Heure locale :", local_time)

Sortie :

Fuseau détecté : America/Los_Angeles
Heure locale : 2025-07-05 05:00:00-07:00

Cette méthode prend en compte les règles régionales et l’heure d’été (DST) avec précision.

Option 2 — Approximation à partir de la longitude

Si vous traitez un grand volume de données (par ex. détections satellitaires), vous pouvez approximer l’heure locale solaire à partir de la longitude :

Chaque 15° de longitude correspond à environ 1 heure de décalage par rapport à l’UTC.

Formule :

1
heure_locale  heure_UTC + (longitude / 15 heures)

Cette méthode suppose que le midi solaire se produit quand le Soleil est à la verticale du méridien local — suffisante pour les analyses climatologiques ou les cycles diurnes.

Exemple :

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

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)
})

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

print(df)

Sortie :

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

⚠️ Cette méthode n’inclut pas les fuseaux irréguliers (ex. : Inde UTC+5:30) ni l’heure d’été, mais elle est idéale pour les études globales de cycle diurne.

Exemple concret — Calcul du cycle diurne du FRP

Prenons un jeu de données avec les colonnes :

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 — Méthode précise (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
import pandas as pd
from datetime import datetime
from zoneinfo import ZoneInfo
from timezonefinder import TimezoneFinder

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 basée sur la longitude

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)

Visualiser le cycle diurne du FRP

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("🔥 Cycle diurne du FRP selon l’heure locale")
plt.xlabel("Heure locale")
plt.ylabel("FRP moyen (MW)")
plt.grid(True)
plt.show()

FRP Diurnal Cycle
FRP Diurnal Cycle

Résumé

Approche Méthode Précision Vitesse Gère l’heure d’été Cas d’usage
timezonefinder + ZoneInfo Détection exacte du fuseau ✅ Élevée 🐢 Plus lente ✅ Oui Recherche, rapports
Longitude / 15 Approximation solaire ⚠️ Moyenne ⚡ Très rapide ❌ Non Analyses globales

Références

Liens Site
Python datetime — objets de date et heure Documentation officielle Python
Python zoneinfo — prise en charge des fuseaux horaires IANA Documentation officielle Python
pandas.to_datetime() Référence API pandas
pandas.Series.dt.tz_convert() Référence API pandas
timezonefinder sur PyPI Index Python Package (PyPI)
Documentation de timezonefinder Documentation officielle
Base de données IANA des fuseaux horaires Source des données utilisées par zoneinfo
Image

of