Python-Zeitzonenkonvertierung

76

Ich suche nach einer schnellen Möglichkeit, eine Zeit einzugeben und sie dann in andere Zeitzonen umzuwandeln (möglicherweise bis zu 10 verschiedene Zeitzonen).

Es tut uns leid. Ich bin mit der Zeit in Python überhaupt nicht vertraut, wenn mich jemand in die richtige Richtung bringen könnte, würde ich es wirklich schätzen.

Bemühen
quelle

Antworten:

97

Ich habe festgestellt, dass der beste Ansatz darin besteht, den "Moment" von Interesse in ein utc-timezone-fähiges datetime-Objekt zu konvertieren (in Python ist die timezone-Komponente für datetime- Objekte nicht erforderlich ).

Dann können Sie Astimezone verwenden , um in die interessierende Zeitzone ( Referenz ) zu konvertieren .

from datetime import datetime
import pytz

utcmoment_naive = datetime.utcnow()
utcmoment = utcmoment_naive.replace(tzinfo=pytz.utc)

# print "utcmoment_naive: {0}".format(utcmoment_naive) # python 2
print("utcmoment_naive: {0}".format(utcmoment_naive))
print("utcmoment:       {0}".format(utcmoment))

localFormat = "%Y-%m-%d %H:%M:%S"

timezones = ['America/Los_Angeles', 'Europe/Madrid', 'America/Puerto_Rico']

for tz in timezones:
    localDatetime = utcmoment.astimezone(pytz.timezone(tz))
    print(localDatetime.strftime(localFormat))

# utcmoment_naive: 2017-05-11 17:43:30.802644
# utcmoment:       2017-05-11 17:43:30.802644+00:00
# 2017-05-11 10:43:30
# 2017-05-11 19:43:30
# 2017-05-11 13:43:30

Mit dem Moment des Interesses an der lokalen Zeitzone (einer Zeit, die existiert ) konvertieren Sie sie wie folgt in utc ( Referenz ).

localmoment_naive = datetime.strptime('2013-09-06 14:05:10', localFormat)

localtimezone = pytz.timezone('Australia/Adelaide')

try:
    localmoment = localtimezone.localize(localmoment_naive, is_dst=None)
    print("Time exists")

    utcmoment = localmoment.astimezone(pytz.utc)

except pytz.exceptions.NonExistentTimeError as e:
    print("NonExistentTimeError")
Juan
quelle
6
Beachten Sie, dass die Ortszeit möglicherweise nicht eindeutig ist und die angegebene Zeichenfolge möglicherweise keiner vorhandenen Zeit entspricht, z. B. aufgrund von Sommerzeitübergängen. Geben localize(is_dst=None)Sie an, ob Sie in solchen Fällen eine Ausnahme auslösen möchten.
JFS
52

Mit Pytz

from datetime import datetime
from pytz import timezone

fmt = "%Y-%m-%d %H:%M:%S %Z%z"
timezonelist = ['UTC','US/Pacific','Europe/Berlin']
for zone in timezonelist:

    now_time = datetime.now(timezone(zone))
    print now_time.strftime(fmt)
Shiva
quelle
10
Hinweis: Es werden verschiedene Zeitmomente in verschiedenen Zeitzonen gedruckt . OP fragt nach dem gleichen Zeitpunkt in verschiedenen Zeitzonen.
JFS
@jfs Nein, tut es nicht - ich lief nur diese und es gedruckt 2018-07-12 13:46:17 UTC+0000, 2018-07-12 06:46:17 PDT-0700und 2018-07-12 15:46:17 CEST+0200, die alle den gleichen Zeitpunkt darstellen.
Mark Amery
@MarkAmery: Versuchen Sie, dem fmt( "%f") Mikrosekunden hinzuzufügen, um festzustellen , dass die Zeitinstanzen unterschiedlich sind.
JFS
1
@jfs Ah, ich habe deinen Kommentar falsch verstanden! Ich dachte, Sie behaupten, dass die Momente völlig unterschiedliche Momente (dh Stunden voneinander entfernt) darstellen, nicht nur, dass sie durch die wenigen Mikrosekunden zwischen den datetime.now(...)Anrufen getrennt sind.
Mark Amery
17
import datetime
import pytz

def convert_datetime_timezone(dt, tz1, tz2):
    tz1 = pytz.timezone(tz1)
    tz2 = pytz.timezone(tz2)

    dt = datetime.datetime.strptime(dt,"%Y-%m-%d %H:%M:%S")
    dt = tz1.localize(dt)
    dt = dt.astimezone(tz2)
    dt = dt.strftime("%Y-%m-%d %H:%M:%S")

    return dt

- -

  • dt: Datum Uhrzeit Zeichenfolge
  • tz1: anfängliche Zeitzone
  • tz2: Zielzeitzone

- -

> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "PST8PDT")
'2017-05-13 05:56:32'

> convert_datetime_timezone("2017-05-13 14:56:32", "Europe/Berlin", "UTC")
'2017-05-13 12:56:32'

- -

> pytz.all_timezones[0:10]
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 'Africa/Algiers',
 'Africa/Asmara',
 'Africa/Asmera',
 'Africa/Bamako',
 'Africa/Bangui',
 'Africa/Banjul',
 'Africa/Bissau']
Raffael
quelle
8

Um eine Zeit in einer Zeitzone in eine andere Zeitzone in Python zu konvertieren, können Sie Folgendes verwendendatetime.astimezone() :

time_in_new_timezone = time_in_old_timezone.astimezone(new_timezone)

Gegeben aware_dt(ein datetimeObjekt in einer bestimmten Zeitzone), um es in andere Zeitzonen zu konvertieren und die Zeiten in einem bestimmten Zeitformat zu drucken:

#!/usr/bin/env python3
import pytz  # $ pip install pytz

time_format = "%Y-%m-%d %H:%M:%S%z"
tzids = ['Asia/Shanghai', 'Europe/London', 'America/New_York']
for tz in map(pytz.timezone, tzids):
    time_in_tz = aware_dt.astimezone(tz)
    print(f"{time_in_tz:{time_format}}")

Wenn die f""Syntax nicht verfügbar ist, können Sie sie durch ersetzen"".format(**vars())

wo Sie aware_dtab der aktuellen Zeit in der lokalen Zeitzone einstellen können :

from datetime import datetime
import tzlocal  # $ pip install tzlocal

local_timezone = tzlocal.get_localzone()
aware_dt = datetime.now(local_timezone) # the current time

Oder aus der Eingabezeitzeichenfolge in der lokalen Zeitzone:

naive_dt = datetime.strptime(time_string, time_format)
aware_dt = local_timezone.localize(naive_dt, is_dst=None)

wo time_stringkönnte aussehen wie : '2016-11-19 02:21:42'. Es entspricht time_format = '%Y-%m-%d %H:%M:%S'.

is_dst=NoneErzwingt eine Ausnahme, wenn die Eingabezeitzeichenfolge einer nicht vorhandenen oder mehrdeutigen Ortszeit entspricht, z. B. während eines Sommerzeitübergangs. Sie könnten auch passieren is_dst=False, is_dst=True. Weitere Links finden Sie unter Python: Wie konvertieren Sie Datum / Uhrzeit / Zeitstempel von einer Zeitzone in eine andere Zeitzone?

jfs
quelle
5

Bitte beachten Sie: Der erste Teil dieser Antwort ist oder Version 1.x des Pendels. Unten finden Sie eine Antwort auf Version 2.x.

Ich hoffe ich bin nicht zu spät!

Die Pendelbibliothek zeichnet sich durch diese und andere Datums- / Zeitberechnungen aus.

>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.datetime.strptime(heres_a_time, '%Y-%m-%d %H:%M %z')
>>> for tz in some_time_zones:
...     tz, pendulum_time.astimezone(tz)
...     
('Europe/Paris', <Pendulum [1996-03-25T17:03:00+01:00]>)
('Europe/Moscow', <Pendulum [1996-03-25T19:03:00+03:00]>)
('America/Toronto', <Pendulum [1996-03-25T11:03:00-05:00]>)
('UTC', <Pendulum [1996-03-25T16:03:00+00:00]>)
('Canada/Pacific', <Pendulum [1996-03-25T08:03:00-08:00]>)
('Asia/Macao', <Pendulum [1996-03-26T00:03:00+08:00]>)

Antwort listet die Namen der Zeitzonen auf, die mit dem Pendel verwendet werden können. (Sie sind die gleichen wie für Pytz.)

Für Version 2:

  • some_time_zones ist eine Liste der Namen der Zeitzonen, die in einem Programm verwendet werden können
  • heres_a_time ist eine Abtastzeit mit einer Zeitzone in der Form '-0400'.
  • Ich beginne damit, die Zeit für die nachfolgende Verarbeitung in eine Pendelzeit umzuwandeln
  • Jetzt kann ich zeigen, wie spät es in jeder Zeitzone ist show_time_zones

...

>>> import pendulum
>>> some_time_zones = ['Europe/Paris', 'Europe/Moscow', 'America/Toronto', 'UTC', 'Canada/Pacific', 'Asia/Macao']
>>> heres_a_time = '1996-03-25 12:03 -0400'
>>> pendulum_time = pendulum.from_format('1996-03-25 12:03 -0400', 'YYYY-MM-DD hh:mm ZZ')
>>> for tz in some_time_zones:
...     tz, pendulum_time.in_tz(tz)
...     
('Europe/Paris', DateTime(1996, 3, 25, 17, 3, 0, tzinfo=Timezone('Europe/Paris')))
('Europe/Moscow', DateTime(1996, 3, 25, 19, 3, 0, tzinfo=Timezone('Europe/Moscow')))
('America/Toronto', DateTime(1996, 3, 25, 11, 3, 0, tzinfo=Timezone('America/Toronto')))
('UTC', DateTime(1996, 3, 25, 16, 3, 0, tzinfo=Timezone('UTC')))
('Canada/Pacific', DateTime(1996, 3, 25, 8, 3, 0, tzinfo=Timezone('Canada/Pacific')))
('Asia/Macao', DateTime(1996, 3, 26, 0, 3, 0, tzinfo=Timezone('Asia/Macao')))
Bill Bell
quelle
AttributeError: 'function' Objekt hat kein Attribut 'strptime'
Seth Connell
1
Pendel ist erstaunlich, aber denken Sie daran, dass die Ausgabe möglicherweise nicht mit dem kompatibel ist, was Sie als Nächstes tun möchten, z. B. Pandas-Datenrahmen.
Turanga1
4

Python 3.9 fügt das zoneinfoModul hinzu, sodass jetzt nur noch die Standardbibliothek benötigt wird!

>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime

>>> d = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo('America/Los_Angeles'))
>>> d.astimezone(ZoneInfo('Europe/Berlin'))  # 12:00 in Cali will be 20:00 in Berlin
datetime.datetime(2020, 10, 31, 20, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))

Wikipedia-Liste der verfügbaren Zeitzonen


Einige Funktionen wie now()und utcnow()geben zeitzonenunabhängige Datenzeiten zurück, dh sie enthalten keine Zeitzoneninformationen . Ich empfehle, nur zeitzonenbezogene Werte mit dem Schlüsselwort anzufordern tz=ZoneInfo('localtime').

Wenn astimezoneeine zeitzonenunabhängige Eingabe angezeigt wird, wird davon ausgegangen, dass es sich um eine Ortszeit handelt , was zu Fehlern führen kann:

>>> datetime.utcnow()  # UTC -- NOT timezone-aware!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 376479)
>>> datetime.now()     # Local time -- NOT timezone-aware!!
datetime.datetime(2020, 6, 2, 0, 39, 57, 376675)

>>> datetime.now(tz=ZoneInfo('localtime'))  # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376806, tzinfo=zoneinfo.ZoneInfo(key='localtime'))
>>> datetime.now(tz=ZoneInfo('Europe/Berlin'))  # timezone-aware
datetime.datetime(2020, 6, 2, 0, 39, 57, 376937, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))
>>> datetime.utcnow().astimezone(ZoneInfo('Europe/Berlin'))  # WRONG!!
datetime.datetime(2020, 6, 1, 22, 39, 57, 377562, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin'))

Windows hat keine Systemzeitzonendatenbank, daher wird hier ein zusätzliches Paket benötigt:

pip install tzdata  

Es gibt einen Backport, der die Verwendung in Python 3.6 bis 3.8 ermöglicht :

sudo pip install backports.zoneinfo

Dann:

from backports.zoneinfo import ZoneInfo
xjcl
quelle
3

Zeitumrechnung

Um eine Zeit in einer Zeitzone in eine andere Zeitzone in Python zu konvertieren, können Sie datetime.astimezone () verwenden:

Der folgende Code dient zum Konvertieren der Ortszeit in eine andere Zeitzone.

  • datetime.datetime.today () - Gibt die aktuelle Ortszeit zurück
  • datetime.astimezone () - konvertiert die Zeitzone, aber wir müssen die Zeitzone übergeben.
  • pytz.timezone ('Asia / Kolkata') - Übergabe der Zeitzone an das pytz-Modul
  • Strftime - Konvertiert Datetime in String
# Time conversion from local time
import datetime
import pytz
dt_today = datetime.datetime.today()   # Local time
dt_India = dt_today.astimezone(pytz.timezone('Asia/Kolkata')) 
dt_London = dt_today.astimezone(pytz.timezone('Europe/London'))
India = (dt_India.strftime('%m/%d/%Y %H:%M'))
London = (dt_London.strftime('%m/%d/%Y %H:%M'))
print("Indian standard time: "+India+" IST")
print("British Summer Time: "+London+" BST")

liste alle Zeitzonen auf

import pytz
for tz in pytz.all_timezones:
    print(tz)
Naresh Kumar
quelle
2

Für Python 3.2+ ist simple-date ein Wrapper um Pytz, der versucht, die Dinge zu vereinfachen.

Wenn Sie ein timedann haben

SimpleDate(time).convert(tz="...")

kann machen was du willst. Zeitzonen sind jedoch recht komplexe Dinge, so dass es erheblich komplizierter werden kann - siehe die Dokumente .

Andrew Cooke
quelle
0
# Program
import time
import os

os.environ['TZ'] = 'US/Eastern'
time.tzset()
print('US/Eastern in string form:',time.asctime()) 

os.environ['TZ'] = 'Australia/Melbourne'
time.tzset()
print('Australia/Melbourne in string form:',time.asctime())

os.environ['TZ'] = 'Asia/Kolkata'
time.tzset()
print('Asia/Kolkata in string form:',time.asctime()) 
Sahil Soni
quelle
2
Hallo und willkommen bei Stack Overflow! Bitte lesen Sie How to Answer und denken Sie immer daran, dass Sie nicht nur dem OP, sondern auch zukünftigen Lesern dieser Frage antworten, insbesondere angesichts der Tatsache, dass diese bereits 8 Jahre alt ist. Bitte bearbeiten Sie Ihren Beitrag, um eine Erklärung zu enthalten, warum dies funktionieren würde.
Adriaan
@Sahil Soni - Bitte geben Sie Antworten mit den richtigen Beschreibungen und Erklärungen
Saikat Saha