RFC 3339 時間を通常のPythonタイムスタンプに変換する簡単な方法はありますか?
ATOMフィードを読み取っているスクリプトがあり、ATOMフィードのアイテムのタイムスタンプを比較できるようにしたいと思います。ファイルの変更時間。
ATOM仕様 から、ATOM日付にはタイムゾーンオフセット(Z<a number>
)しかし、私の場合、Z
の後には何もないので、GMTを想定できると思います。
ある種の正規表現を使用して時間を解析できると思いますが、Pythonには、見つけることができなかった組み込みの方法があることを期待していました。
組み込みはありません、afaik。
feed.date.rfc3339これはPython RFC3339形式のタイムスタンプ文字列を=に変換する関数を備えたライブラリモジュールです。 Pythonタイムフロート値、およびその逆。RFC3339は、Atomフィードシンジケーション形式で使用されるタイムスタンプ形式です。
BSDライセンスです。
http://home.blarg.net/~steveha/pyfeed.html
(編集したので、私が書いていなかったのは明らかです。:-)
例は含まれていませんが、Zオフセットまたはタイムゾーンがなく、期間ではなく基本時間だけが必要であると仮定すると、おそらくこれが適しています。
import datetime as dt
>>> dt.datetime.strptime('1985-04-12T23:20:50.52', '%Y-%m-%dT%H:%M:%S.%f')
datetime.datetime(1985, 4, 12, 23, 20, 50, 520000)
Strptime()関数がPython 2.5のdatetimeモジュールに追加されたため、まだそこにあることを知らない人もいます。
編集:time.strptime()関数はしばらくの間存在していましたが、ほぼ同じように機能してstruct_time値を提供します。
>>> ts = time.strptime('1985-04-12T23:20:50.52', '%Y-%m-%dT%H:%M:%S.%f')
>>> ts
time.struct_time(tm_year=1985, tm_mon=4, tm_mday=12, tm_hour=23, tm_min=20, tm_sec=50, tm_wday=4, tm_yday=102, tm_isdst=-1)
>>> time.mktime(ts)
482210450.0
RFC3339のdatetime形式で多くの苦労をしましたが、date_string <=> datetime_objectを両方向に変換するための適切な解決策を見つけました。
2つの異なる外部モジュールが必要です。そのうちの1つは、一方向にしか変換を実行できないためです(残念ながら)。
最初のインストール:
Sudo pip install rfc3339
Sudo pip install iso8601
次に、以下を含めます。
import datetime # for general datetime object handling
import rfc3339 # for date object -> date string
import iso8601 # for date string -> date object
どのモジュールがどの方向に向いているかを覚えておく必要がないため、2つの簡単なヘルパー関数を作成しました。
def get_date_object(date_string):
return iso8601.parse_date(date_string)
def get_date_string(date_object):
return rfc3339.rfc3339(date_object)
コード内で次のように簡単に使用できます。
input_string = '1989-01-01T00:18:07-05:00'
test_date = get_date_object(input_string)
# >>> datetime.datetime(1989, 1, 1, 0, 18, 7, tzinfo=<FixedOffset '-05:00' datetime.timedelta(-1, 68400)>)
test_string = get_date_string(test_date)
# >>> '1989-01-01T00:18:07-05:00'
test_string is input_string # >>> True
ふれか!これで、日付文字列と日付文字列を使用可能な形式で簡単に(haha)使用できます。
http://pypi.python.org/pypi/iso8601/ RFC3339がサブセットであるiso8601を解析できるようです。おそらくこれは役立つかもしれませんが、やはり構築されていません-に。
http://bugs.python.org/issue1587 (重複 http://bugs.python.org/issue5207 )
現時点では組み込みがないようです。
feedparser.py は、実際のatom/rssフィードで発生する可能性のあるさまざまな日付形式を解析するための堅牢で拡張可能な方法を提供します。
>>> from feedparser import _parse_date as parse_date
>>> parse_date('1985-04-12T23:20:50.52Z')
time.struct_time(tm_year=1985, tm_mon=4, tm_mday=12, tm_hour=23, tm_min=20,
tm_sec=50, tm_wday=4, tm_yday=102, tm_isdst=1)
Djangoを使用している場合は、Djangoの関数を使用できます parse_datetime
:
>>> from Django.utils.dateparse import parse_datetime
>>> parse_datetime("2016-07-19T07:30:36+05:00")
datetime.datetime(2016, 7, 19, 7, 30, 36, tzinfo=<Django.utils.timezone.FixedOffset object at 0x101c0c1d0>)
これを試してみてください、それは私にとってはうまくいきます
datetime_obj = datetime.strptime("2014-01-01T00:00:00Z", '%Y-%m-%dT%H:%M:%SZ')
または
datetime_obj = datetime.strptime("Mon, 01 Jun 2015 16:41:40 GMT", '%a, %d %b %Y %H:%M:%S GMT')
Python 3を使用すると、RegExを使用してRFC 3339タイムスタンプをコンポーネントに分割できます。次に、datetimeオブジェクトを直接作成します。追加のモジュールは必要ありません。
import re
import datetime
def parse_rfc3339(dt):
broken = re.search(r'([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(\.([0-9]+))?(Z|([+-][0-9]{2}):([0-9]{2}))', dt)
return(datetime.datetime(
year = int(broken.group(1)),
month = int(broken.group(2)),
day = int(broken.group(3)),
hour = int(broken.group(4)),
minute = int(broken.group(5)),
second = int(broken.group(6)),
microsecond = int(broken.group(8) or "0"),
tzinfo = datetime.timezone(datetime.timedelta(
hours = int(broken.group(10) or "0"),
minutes = int(broken.group(11) or "0")))))
この例では、タイムゾーンまたはマイクロ秒が「0」として欠落していますが、追加のエラーチェックが必要な場合があります。乾杯、アレックス
新しい datetime.fromisoformat(date_string) メソッドは Python 3.7 に追加されました)は、タイムゾーンを持つものを含むほとんどのRFC3339タイムスタンプを解析します完全な実装ではないため、必ずユースケースをテストしてください。
>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00')
datetime.datetime(2011, 11, 4, 0, 5, 23,
tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
rfc3339ライブラリ: http://henry.precheur.org/python/rfc3339
別の質問で素晴らしい dateutil.parser モジュールに出くわし、RFC3339の問題で試してみましたが、この質問の他のどの応答よりも正気ですべてを処理しているようです。