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 を使用してデータベースにロードできるように、これを行っています。

私は基本的に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(' ')です。

4

5 に答える 5

15

isoformatdatetimeは、範囲の制限がないインスタンスで機能します。

>>> 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

これは、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 に答える
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 に答える
1

これは、ctime ライブラリ (UTF) の「機能」です。また、2038 を超えると問題が発生する可能性があります。

于 2009-10-29T14:10:09.143 に答える