2017-01-12 4 views
1

Ich versuche, einen Zeitstempel mit einer bestimmten Zeitzone (Europa/Paris) in ein Datetime-Format in UTC zu konvertieren. Von meinem Laptop funktioniert es mit der Lösung unten, aber wenn ich meinen Code auf einem Remote-Server (AWS-Lambda-Funktion in Irland) ausführe, habe ich eine Verschiebung von 1 Stunde, weil die lokale Zeitzone des Servers sich von meiner unterscheidet . Wie kann ich einen Code haben, der auf meinem Laptop und gleichzeitig auf einem Remote-Server arbeiten kann (dynamisch mit lokaler Zeitzone umgehen)?Python konvertieren Zeitstempel mit bestimmter Zeitzone zu Datum in UTC

import pytz 
import datetime 

def convert_timestamp_in_datetime_utc(timestamp_received): 
    utc = pytz.timezone('UTC') 
    now_in_utc = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(pytz.UTC) 
    fr = pytz.timezone('Europe/Paris') 
    new_date = datetime.datetime.fromtimestamp(timestamp_received) 
    return fr.localize(new_date, is_dst=None).astimezone(pytz.UTC) 

Dank

+0

Ich bin mir nicht sicher, ob ich die Frage verstehe - wie scheitert das? Was ist "timestamp_received"? Ich kann mir diesen Fehler nur vorstellen, wenn der Zeitstempel ein Zeitstempel in * Ortszeit * ist. – Paul

+0

Es ist ein Zeitstempel von einer französischen Website, die auf der lokalen Zeitzone (Europa/Paris) basiert. Wenn ich diese Funktion ausgeführt habe, hat das return datetime eine Verschiebung von einer Stunde, wenn ich es auf meinem Laptop oder mit einer Lambda-Funktion ausgeführt habe. Ich nehme an, das Problem ist, dass "datetime.datetime.fromtimestamp" auf der lokalen Zeitzone basiert ... – Matt

Antwort

1

Ich bin nicht sicher, was timestamp_received ist, aber ich denke, was Sie wollen, utcfromtimestamp()

import pytz 
from datetime import datetime 

def convert_timestamp_in_datetime_utc(timestamp_received): 
    dt_naive_utc = datetime.utcfromtimestamp(timestamp_received) 
    return dt_naive_utc.replace(tzinfo=pytz.utc) 

Der Vollständigkeit halber hier ist ein weiterer Weg, um das Gleiche zu erreichen python-dateutil durch Bezugnahme auf tzlocal Zeitzone:

from dateutil import tz 
from datetime import datetime 
def convert_timestamp_in_datetime_utc(timestamp_received): 
    dt_local = datetime.fromtimestamp(timestamp_received, tz.tzlocal()) 

    if tz.datetime_ambiguous(dt_local): 
     raise AmbiguousTimeError 

    if tz.datetime_imaginary(dt_local): 
     raise ImaginaryTimeError 

    return dt_local.astimezone(tz.tzutc()) 


class AmbiguousTimeError(ValueError): 
    pass 

class ImaginaryTimeError(ValueError): 
    pass 

(Ich fügte in den AmbiguousTimeError und ImaginaryTimeError Bedingungen, um die pytz Schnittstelle zu imitieren.) Beachten Sie, dass ich dies nur für den Fall, dass Sie ein ähnliches Problem haben, die aus irgendeinem Grund auf die lokale Zeitzone verweisen müssen - wenn Sie etwas haben das wird Ihnen die richtige Antwort in UTC, ist es am besten, dass zu verwenden und dann astimezone verwenden, um es in zu bekommen, was auch immer lokale Zone Sie wollen in.

So funktioniert es

Da Sie zum Ausdruck gebracht, dass du immer noch ein wenig verwirrt darüber, wie das in den Kommentaren funktioniert, dachte ich, ich würde erklären, warum das funktioniert. Es gibt zwei Funktionen, die Zeitstempel zu datetime.datetime Objekte konvertieren, datetime.datetime.fromtimestamp(timestamp, tz=None) und datetime.datetime.utcfromtimestamp(timestamp):

  1. utcfromtimestamp(timestamp) Sie geben ein naivedatetime, die die Zeit in UTC darstellt. Sie können dann dt.replace(tzinfo=pytz.utc) (oder eine andere utc Implementierung - , dateutil.tz.tzutc(), usw.) tun, um eine bewusste Datetime zu erhalten und sie in die gewünschte Zeitzone zu konvertieren.

  2. fromtimestamp(timestamp, tz=None), wenn tz nicht None ist, werden Sie ein bewusstdatetime entspricht utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(tz) geben. Wenn tzNone ist, wird die angegebene Zeitzone nicht konvertiert, sondern in Ihre lokale Zeit konvertiert (entspricht dateutil.tz.tzlocal()). Anschließend wird eine naivedatetime zurückgegeben.

Ab Python 3.6 können Sie datetime.datetime.astimezone(tz=None) auf naive Datetimes verwenden, und die Zeitzone sein System Ortszeit angenommen wird. Wenn Sie also eine Python> = 3.6-Anwendung oder -Bibliothek entwickeln, können Sie datetime.fromtimestamp(timestamp).astimezone(whatever_timezone) oder datetime.utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(whatever_timezone) als Entsprechungen verwenden.

+0

Vielen Dank Paul, es funktioniert mit der ersten Lösung! Immer noch verwirrend für mich die Datetime/Timestamp-Manipulation mit unterschiedlicher Zeitzone :( – Matt

+0

@Matt habe ich meine Antwort aktualisiert, hoffentlich klärt das auf. – Paul

+0

vielen Dank für deine Erklärung! Es ist jetzt klarer für mich. – Matt

Verwandte Themen