os.stat().st_mtime als String speichern und vergleichen...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 5. September 2008, 16:40

In meinem kleinen MD5sum_calc Skript möchte ich gern das Dateidatum (os.stat().st_mtime) in eine Textdatei speichern. In einem späteren Programm lauf, soll der gespeicherte Wert mit dem aktuellen mtime verglichen werden.

Das erste Problem ist die Zeitzone: Eigentlich hätte ich gern das immer localtime angezeigt wird, weil man es die Zeiten manuell vergleichen kann (Also mit der Angabe in den Eigenschaften der Datei bzw. die Datei Explorer)

Ich hab ein wenig Probiert und mit eine tzinfo gebaut. Aber das ist alles nicht so einfach zu machen. Also speicher ich es doch in UTC und fertig. Zusätzlich könnte ich noch die Information mit speichern:

Code: Alles auswählen

if time.daylight != 0:
    # Sommerzeit
    offset=-time.altzone
else:
    # keine Sommerzeit
    offset=-time.timezone

offset_string = "%+dsec. (%s)" % (offset, time.tzname[1])
Nicht ganz klar ist, ob ich überhaupt eine Unterscheidung machen muß zwischen Sommerzeit oder nicht. Könnte ich nicht einfach immer time.altzone nehmen?

Jedenfalls kommt sowas raus:
+7200sec. (Mitteleuropäische Sommerzeit)
(wobei das ä z.Z. noch Encoding Probleme bereitet, aber egal.)



Das nächste Problem sind die microsekunden. mtime liefert diese ja zurück.
Theoretisch kann ich beim datetime.strftime() Format String statt "%s" (Normale Sekunden) ein "%f" (Microsekunden) nehmen.

Das rückwandeln mit strptime geht aber nicht mit %f!
Ab Python 2.5 könnte man es so machen:

Code: Alles auswählen

datetime.datetime.strptime(datetime_string, DATETIME_FORMAT)
# geht nicht:
Traceback (most recent call last):
  File "test.py", line 40, in <module>
    dt3 = datetime.datetime.strptime(datetime_string, DATETIME_FORMAT)
  File "C:\Python25\lib\_strptime.py", line 320, in strptime
    (bad_directive, format))
ValueError: 'f' is a bad directive in format '%a, %d %b %Y %H:%M:%f'
Vor Python 2.5 gibt kein datetime.strptime also muß man über time gehen, funktioniert natürlich auch nicht, weil %f nicht gibt:

Code: Alles auswählen

time.mktime(time.strptime(datetime_string, DATETIME_FORMAT))
# geht auch nicht
Traceback (most recent call last):
  File "test.py", line 30, in <module>
    timestamp = time.mktime(time.strptime(datetime_string, DATETIME_FORMAT))
  File "C:\Python25\lib\_strptime.py", line 320, in strptime
    (bad_directive, format))
ValueError: 'f' is a bad directive in format '%a, %d %b %Y %H:%M:%f'
z.Z. sehe ich also nicht, wie man die microsekunden in einen String und wieder zurück bekommt, ohne das Parsen selber übernehmen zu müßen. Übersehe ich da was?

Ein externes Zusatzmodul möchte ich nicht nehmen.

EDIT: Was mir gerade einfällt, speziell für mein kleines Skript brauche ich eigentlich keine Rückwandlung des Datetime-Strings. Ich generieren einfach nochmal den String von mtime und vergleiche die Strings.
Dennoch wäre es nett, wenn es dazu eine Lösung gibt!

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 5. September 2008, 16:57

Was mir einfallen würde ist einfach die Mikrosekunden streichen und wie das universelle RFC 2822-Zeitformat zu verwenden. Andererseits ist es schon interessant das ISO 8601 zwar geschrieben, nicht aber geparst werden kann. Na immerhin gibt es noch die guten alten Timestamps.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 5. September 2008, 17:12

Ja, das wäre eine Möglichkeit. Aber wie gesagt, ich hab ja schon eine Lösung. Dennoch ist es mal interessant nach den Micosekunden zu schauen.

Noch was, hab ich da vielleicht einen Bug in Python 2.5 gefunden:

Code: Alles auswählen

import datetime

print "1", datetime.datetime(2008,1,1).strftime("%a, %d %b %Y %H:%M:%s")
print "2", datetime.datetime(2008,1,1).strftime("%a, %d %b %Y %H:%M:%S")
Ausgabe:
1
2 Tue, 01 Jan 2008 00:00:00
Der Erste Formatstring ist falsch, statt einem großen %S ist dort ein kleines %s... Normalerweise sollte da IMHO sowas kommen: ValueError: 's' is a bad directive in format '%a, %d %b %Y %H:%M:%s' Statt dessen bekommt man nur einen Leeren String zurück, warum?

EDIT: Also konkret habe ich jetzt mein Problem so gelöst: http://trac.pylucid.net/changeset/1745

Hab noch ein paar Ungereimtheiten im datetime Modul entdeckt.

Code: Alles auswählen

datetime( year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]) 
date( year, month, day) 
time( hour[, minute[, second[, microsecond[, tzinfo]]]]) 

timedelta( [days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) 
Warum wird bei timedelta alle Parameter in Mehrzahl angegeben?

Dumm ist auch, das Werte nicht automatisch umgerechnet werden können. Wäre doch schön, wenn man das machen könnte: datetime.time(second=7200) Aber: ValueError: second must be in 0..59

Also irgendwie ist das ganze datetime + time Modul nicht gut durchdacht. Tut sich da eigentlich was in Python v3?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
lunar

Samstag 6. September 2008, 10:54

Wieso nimmst du nicht einfach "mx.DateTime"?
Benutzeravatar
snafu
User
Beiträge: 5536
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Samstag 6. September 2008, 17:03

lunar hat geschrieben:Wieso nimmst du nicht einfach "mx.DateTime"?
Er sagte ja, dass er keine externen Module nehmen will.
lunar

Sonntag 7. September 2008, 12:27

Stimmt, hatte ich übersehen. Allerdings würde dieses Modul die ganze Sache erheblich vereinfachen, dass bringt nämlich bereits einen ISO-Parser mit.
Antworten