Pergunta

Eu não percebi isso, mas aparentemente função strftime do Python não suporta datas antes de 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

Eu tenho certeza que eu poderia cortar juntos algo me a fazer isso, mas eu acho que a função strftime está lá por uma razão (e há também uma razão pela qual não pode suportar pré-1900 datas). Eu preciso ser capaz de suportar datas antes de 1900. Eu tinha acabado de usar str, mas não há muita variação. Em outras palavras, ele pode ou não pode ter microssegundos ou pode ou não pode ter um fuso horário. Existe alguma solução para isso?

Se ele faz a diferença, eu estou fazendo isso para que eu possa gravar os dados em um arquivo de texto e carregá-lo em um banco de dados usando o Oracle SQL * Loader.

I essencialmente acabou fazendo a resposta de Alex Martelli. Aqui está uma implementação mais completa:

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

A única diferença é que str(d) é equivalente a d.isoformat(' ').

Foi útil?

Solução

isoformat funciona em instâncias datetime w / o limitação do intervalo:

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

Se precisar de uma cadeia diferente do formato que não é muito difícil de fatia, dados e peças de remix da sequência que começa a partir de isoformat, que é muito consistente (YYYY-MM-DDTHH:MM:SS.mmmmmm, com o ponto e seguintes microssegundos omitido se microssegundos são zero).

Outras dicas

A documentação parece bastante claro sobre isso:

O intervalo exato de anos para os quais strftime() funciona também varia entre plataformas. Independentemente da plataforma, anos antes de 1900 não pode ser usado.

Assim lá não vai ser uma solução que usa strftime(). Felizmente, é bastante simples de fazer isso "à mão":

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

mxDateTime pode lidar com datas arbitrárias. módulos time e datetime do Python usar UNIX timestamps internamente, é por isso que eles têm alcance limitado.

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

Esta é a partir do fonte matplotlib . Poderia fornecer um bom ponto de partida para rolar seus próprios.

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)

Este é o "recurso" da biblioteca ctime (UTF). Além disso, você pode ter problema acima 2038.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top