2010-04-05 8 views
6

Ich verwende die folgenden Funktionen:Python 3: Zeitstempel bis datetime: Woher kommt diese zusätzliche Stunde?

# The epoch used in the datetime API. 
EPOCH = datetime.datetime.fromtimestamp(0) 

def timedelta_to_seconds(delta): 
    seconds = (delta.microseconds * 1e6) + delta.seconds + (delta.days * 86400) 
    seconds = abs(seconds) 

    return seconds 

def datetime_to_timestamp(date, epoch=EPOCH): 
    # Ensure we deal with `datetime`s. 
    date = datetime.datetime.fromordinal(date.toordinal()) 
    epoch = datetime.datetime.fromordinal(epoch.toordinal()) 

    timedelta = date - epoch 
    timestamp = timedelta_to_seconds(timedelta) 

    return timestamp 

def timestamp_to_datetime(timestamp, epoch=EPOCH): 
    # Ensure we deal with a `datetime`. 
    epoch = datetime.datetime.fromordinal(epoch.toordinal()) 

    epoch_difference = timedelta_to_seconds(epoch - EPOCH) 
    adjusted_timestamp = timestamp - epoch_difference 

    date = datetime.datetime.fromtimestamp(adjusted_timestamp) 

    return date 

Und sie mit dem übergebenen Code verwendet:

twenty = datetime.datetime(2010, 4, 4) 

print(twenty) 
print(datetime_to_timestamp(twenty)) 
print(timestamp_to_datetime(datetime_to_timestamp(twenty))) 

und die folgenden Ergebnisse erhalten:

2010-04-04 00:00:00 
1270339200.0 
2010-04-04 01:00:00 

Aus irgendeinem Grund ich Ich bekomme eine zusätzliche Stunde im letzten Anruf hinzugefügt, trotz meines Codes, soweit ich sehen kann, keine Mängel.

Woher kommt diese zusätzliche Stunde?

+0

Ist es schon britische Sommerzeit? – msw

+0

@msw Ist das ein versteckter Hinweis über Zeitzonen? ...Es hat vor ungefähr einer Woche angefangen, aber ich sehe nicht, wo in meinem Code es die Informationen der Zeitzone handhabt oder sich naiv verhält, anstatt sich naiv zu verhalten? –

+1

ja, das war ein Hinweis, da ich die gleichen Ergebnisse bekomme und auch bei Tageslicht bin (in Python 2.6). Ich bin jetzt durch die gottverdammte datetime.tzinfo-Operation, während ich darauf warte, dass die Welt auf http://en.wikipedia.org/wiki/Swatch_Internet_Time umschaltet. – msw

Antwort

4
# Ensure we deal with `datetime`s. 
date = datetime.datetime.fromordinal(date.toordinal()) 

(Das ist völlig die Zeit-of-day Abhacken, als ‚Ordnungs‘ nur einen Tag Zahl ist. Ist es das, was Sie tun soll? Ich vermute nicht.)

Wie auch immer, als Michael sagte, datetime.fromtimestamp gibt Ihnen eine naive Datetime entsprechend was local Zeit für diesen POSIX (UTC) Zeitstempel wäre für Sie. Also, wenn Sie anrufen -

date = datetime.datetime.fromtimestamp(adjusted_timestamp) 

Sie die lokale Zeit für den Zeitstempel POSIX immer darstellt 2010-04-04T00: 00: 00, was natürlich in BST ist eine Stunde voraus. Dies geschieht nicht in der Rückkehrrichtung, weil Ihre Epoche im Januar ist, wenn BST nicht in Kraft ist. (Ihre EPOCH wäre aber auch komplett ausgeschaltet, wenn Sie nicht in Großbritannien wären.)

Sie sollten beide Ihre Anwendungen datetime.fromtimestamp durch datetime.utcfromtimestamp ersetzen.

Es ist traurig, dass datetime die schreckliche time Tradition der Einhaltung der Ortszeit fortsetzt. Sie "naiv" zu nennen und die DST-Flagge wegzunehmen, macht sie nur noch schlimmer. Persönlich kann ich es nicht ertragen, datetime zu verwenden und ganze Integer-UTC-Zeitstempel für alles vorzuziehen (Umwandlung in lokale Zeitzonen nur für die Formatierung).

+0

Pythons Datum-Zeit-API hat mir Angst gemacht, es jemals wieder zu benutzen ... –

1

Gemessen an Ihrem Profil befinden Sie sich in Großbritannien. Das bedeutet, dass Sie derzeit aufgrund der Sommerzeit auf UTC + 1 ausgeführt werden.

Wenn ich Ihren Zeitstempel nehme und ihn durch datetime.fromtimestamp auf Python 2.6 (ich weiß, Sie verwenden Python 3, aber das ist, was ich habe), zeigt mir, dass es glaubt, dass es bezieht sich auf 2010-04-04 02 : 00: 00 - und ich bin in CEST, also ist das UTC + 2.

Running datetime.fromtimestamp (0), ich bekomme, dass die Epoche 1970-01-01 01:00:00 ist. Dies zeigt mir dann, dass es korrekt nur eine einzige Stunde hinzufügt (seit dem 1. Januar ist außerhalb der Sommerzeit, und die Epoche ist um Mitternacht UTC an diesem Datum, wäre es 01.00 Uhr hier).

Mit anderen Worten, Ihr Problem ist, dass Sie eine Zeit senden, die DST angewendet hat, aber datetime_to_timestamp behandelt es als ob DST nicht existierte. timestamp_to_datetime wendet jedoch die DST an.

Leider weiß ich nicht genug Python zu wissen, wie Sie das lösen würden, aber das sollte Ihnen zumindest etwas geben, um weiterzumachen.