Est-il possible d'utiliser une fonction de type strftime pour des dates antérieures à 1900 dans Python?

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

Question

Je ne m'en suis pas rendu compte, mais apparemment, la fonction strftime de Python ne prend pas en charge les dates antérieures à 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

Je suis sûr que je pourrais pirater moi-même quelque chose pour le faire, mais je pense que la fonction strftime existe pour une raison (et il y a aussi une raison pour laquelle elle ne peut pas supporter Dates 1900). Je dois pouvoir prendre en charge les dates antérieures à 1900. Je n'utiliserais que str , mais il y a trop de variations. En d'autres termes, il peut ne pas avoir de microsecondes ou ne pas avoir de fuseau horaire. Y a-t-il une solution à cela?

Si cela fait une différence, je le fais pour pouvoir écrire les données dans un fichier texte et les charger dans une base de données à l'aide d'Oracle SQL * Loader.

J'ai fini par faire la réponse d'Alex Martelli. Voici une implémentation plus complète:

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

La seule différence est que str (d) est équivalent à d.isoformat ('') .

Était-ce utile?

La solution

isoformat fonctionne sur instances datetime sans limitation de plage:

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

Si vous avez besoin d'une chaîne de format différent, il n'est pas trop difficile de couper, de dés et de remixer des morceaux de la chaîne que vous obtenez de isoformat , ce qui est très cohérent ( YYYY-MM-DDTHH : MM: SS.mmmmmm , avec le point et les microsecondes suivantes omis si les microsecondes sont égales à zéro).

Autres conseils

La la documentation semble assez claire à ce sujet:

  

La plage exacte d'années de fonctionnement de strftime () varie également d'une plate-forme à l'autre. Quelle que soit la plate-forme, les années antérieures à 1900 ne peuvent pas être utilisées.

Il n’y aura donc pas de solution utilisant strftime () . Heureusement, il est assez simple de faire cela "à la main":

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

mxDateTime peut gérer des dates arbitraires . Les modules time et datetime de Python utilisent des horodatages UNIX en interne, raison pour laquelle leur portée est limitée.

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

Ceci provient du source matplotlib . Cela pourrait constituer un bon point de départ pour lancer le vôtre.

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)

Il s'agit de la "fonctionnalité". de la bibliothèque ctime (UTF). Vous pouvez également avoir un problème au-dessus de 2038.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top