在Python中有没有方法对1900年前的日期使用类似strftime的函数?

20 投票
5 回答
6410 浏览
提问于 2025-04-15 15:29

我之前没注意到,但显然Python的strftime函数不支持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

我相信我可以自己搞定这个问题,但我觉得strftime函数存在是有原因的(而且它不能支持1900年之前的日期也是有原因的)。我需要能够处理1900年之前的日期。我本来想用str,但格式变化太多了。换句话说,日期字符串可能有微秒,也可能没有;可能有时区,也可能没有。有没有什么解决办法呢?

如果这有影响的话,我这么做是为了把数据写入文本文件,然后用Oracle SQL*Loader加载到数据库中。

最后我基本上采用了Alex Martelli的答案。这里有一个更完整的实现:

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

唯一的区别是str(d)等于d.isoformat(' ')

5 个回答

4

mxDateTime 可以处理任意日期。Python 的 timedatetime 模块内部使用的是 UNIX 时间戳,这就是它们日期范围有限的原因。

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
11

这段文档看起来说得很清楚:

strftime()这个函数能处理的年份范围在不同的平台上是有差别的。不过,不管是什么平台,1900年之前的年份是不能用的。

所以,使用strftime()来解决这个问题是不行的。幸运的是,手动处理这个问题其实也很简单:

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

isoformat 方法可以在 datetime 实例上使用,没有范围限制:

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

如果你需要不同格式的字符串,其实从 isoformat 得到的字符串切割、组合一下也不难。这个字符串的格式是很固定的,通常是 YYYY-MM-DDTHH:MM:SS.mmmmmm,如果微秒是零的话,后面的点和微秒部分会被省略。

撰写回答