Gibt es eine Möglichkeit, eine strftime ähnliche Funktion für Termine vor 1900 in Python zu benutzen?

StackOverflow https://stackoverflow.com/questions/1643967

Frage

Ich habe das nicht erkennen, aber anscheinend Pythons strftime Funktion nicht unterstützt Daten vor 1900:

>>> from datetime import datetime
>>> d = datetime(1899, 1, 1)
>>> d.strftime('%Y-%m-%d')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: year=1899 is before 1900; the datetime strftime() methods require year >= 1900

Ich bin sicher, dass ich zusammen etwas hacken konnte mich, dies zu tun, aber ich glaube die strftime Funktion für einen Grund gibt es (und es ist auch ein Grund, warum es nicht vor 1900 Daten unterstützen kann). Ich muss in der Lage, Termine zu unterstützen vor 1900. Ich habe gerade str verwenden würde, aber es ist zu viel Variation. Mit anderen Worten, es kann oder möglicherweise nicht über Mikrosekunden oder es kann oder auch nicht eine Zeitzone hat. Gibt es eine Lösung für dieses?

Wenn es einen Unterschied macht, mache ich das so, dass ich die Daten in eine Textdatei schreiben kann und es in eine Datenbank geladen werden unter Verwendung von Oracle SQL * Loader.

ich endete im Wesentlichen Alex Martelli Antwort tun up. Hier ist eine vollständigere Umsetzung:

>>> from datetime import datetime
>>> d = datetime.now()
>>> d = d.replace(microsecond=0, tzinfo=None)
>>> str(d)
'2009-10-29 11:27:27'

Der einzige Unterschied besteht darin, dass str(d) entspricht d.isoformat(' ').

War es hilfreich?

Lösung

isoformat arbeitet auf datetime Instanzen w / o Begrenzung des Bereichs:

>>> import datetime
>>> x=datetime.datetime(1865, 7, 2, 9, 30, 21)
>>> x.isoformat()
'1865-07-02T09:30:21'

Wenn Sie ein anderes Format String brauchen es nicht zu schwer zu schneiden, Würfel und remix Stücke der Zeichenfolge, die Sie von isoformat bekommen, die sehr konsistent ist (YYYY-MM-DDTHH:MM:SS.mmmmmm, mit dem Punkt und folgende Mikrosekunden weggelassen, wenn Mikrosekunden sind Null).

Andere Tipps

Die Dokumentation scheint ziemlich klar darüber:

  

Der genaue Bereich von Jahren, für die strftime() arbeitet variiert auch über Plattformen hinweg. Unabhängig von der Plattform, Jahre vor 1900 nicht verwendet werden.

So gibt wird nicht eine Lösung sein, die strftime() verwendet. Glücklicherweise ist es ziemlich einfach, diese „von Hand“ zu tun:

>>> "%02d-%02d-%02d %02d:%02d" % (d.year,d.month,d.day,d.hour,d.minute)
'1899-01-01 00:00'

mxDateTime können beliebige Daten verarbeiten. Pythons time und datetime Module verwendet UNIX intern Zeitstempel, das ist, warum sie nur über begrenzte Reichweite.

In [5]: mx.DateTime.DateTime(1899)
Out[5]: <mx.DateTime.DateTime object for '1899-01-01 00:00:00.00' at 154a960>

In [6]: DateTime.DateTime(1899).Format('%Y-%m-%d')
Out[6]: 1899-01-01

Dies ist der matplotlib Quelle . Könnte ein guter Ausgangspunkt, geben Sie Ihre eigenen für Rollen.

def strftime(self, dt, fmt):
    fmt = self.illegal_s.sub(r"\1", fmt)
    fmt = fmt.replace("%s", "s")
    if dt.year > 1900:
        return cbook.unicode_safe(dt.strftime(fmt))

    year = dt.year
    # For every non-leap year century, advance by
    # 6 years to get into the 28-year repeat cycle
    delta = 2000 - year
    off = 6*(delta // 100 + delta // 400)
    year = year + off

    # Move to around the year 2000
    year = year + ((2000 - year)//28)*28
    timetuple = dt.timetuple()
    s1 = time.strftime(fmt, (year,) + timetuple[1:])
    sites1 = self._findall(s1, str(year))

    s2 = time.strftime(fmt, (year+28,) + timetuple[1:])
    sites2 = self._findall(s2, str(year+28))

    sites = []
    for site in sites1:
        if site in sites2:
        sites.append(site)

    s = s1
    syear = "%4d" % (dt.year,)
    for site in sites:
        s = s[:site] + syear + s[site+4:]

    return cbook.unicode_safe(s)

Dies ist das "Feature" der ctime Bibliothek (UTF). Sie können auch problemlos über 2038 haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top