19

我没有意识到这一点,但显然 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 将其加载到数据库中。

我基本上最终做了亚历克斯马泰利的回答。这是一个更完整的实现:

>>> 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(' ')

4

5 回答 5

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如果微秒为零,则省略点和后面的微秒)。

于 2009-10-29T15:07:26.803 回答
11

文档似乎很清楚这一点

作品的确切年份范围strftime()也因平台而异。无论平台如何,都不能使用 1900 年之前的年份。

所以不会有使用strftime(). 幸运的是,“手动”执行此操作非常简单:

>>> "%02d-%02d-%02d %02d:%02d" % (d.year,d.month,d.day,d.hour,d.minute)
'1899-01-01 00:00'
于 2009-10-29T14:12:37.430 回答
3

mxDateTime可以处理任意日期。Pythontimedatetime模块在内部使用 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
于 2009-10-29T14:12:42.750 回答
3

这是来自matplotlib 源。可以为自己滚动提供一个很好的起点。

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)
于 2009-10-29T14:25:46.413 回答
1

这是 ctime 库 (UTF) 的“功能”。此外,您可能在 2038 以上时遇到问题。

于 2009-10-29T14:10:09.143 回答