RSSの日付データはテキスト。その表現形式はUTC,JSTなどがありうる。これらをすべてYYYY-mm-ddTHH:MM:SSZ
形式にしたい。SQLite3DBに登録するために。
やりたいこと
いかなる日付テキストもUTC時刻にしてYYYY-mm-ddTHH:MM:SSZ
形式のテキストにしたい。以下のような簡単なコードで。
feed.entries[i].published_parsed.format('%Y-%m-%dT%H:%M:%SZ')
前回のようにRSS/Atomによって日付テキストの書式規格が異なる。また、同じ規格であっても:
の有無など微妙に異なる書式もあるが規格のうちである。それらに完全対応したい。
結論
Python3.7以降でないと無理っぽい。3.6でもいけるかも。いずれにせよ、私の環境3.5.3では無理。
日時の扱いが難しすぎる件
RSS/Atomにおける日付形式がバラバラ
RSS/Atomパーサにおける日付形式がtime.struct_time
Pythonパッケージfeedparserの話。RSS/Atomからデータを取得するものだが、日付の型が文字列またはtime.struct_timeなせいで、タイムゾーンが簡単に扱えず、JST→UTCなどの時刻変換がむずかしい。
Pythonで日時を扱う方法が統一されておらず難しい
Pythonで日時を扱う方法は複数あるようだ。ふつう日時はdatetime
で扱うことが多いと思うが、feedparserではtime.struct_timeで取得されるらしい。
time.struct_timeでタイムゾーンを取得し、UTCに変換し、フォーマットを指定したい。これを簡単にやる方法はなさそう。それどころか、環境によってはPython3.6以降でないとタイムゾーンが扱えない。私の環境では扱えなかった。
つまり、time.struct_timeで取得できるfeedparser entries[i].published_parsedでは、UTC時刻に変換できない。
文字列→日付型(タイムゾーンに:
があるとエラー)
では、文字列から日付型に変換するのはどうか?
feedparser entries[i].publishedで文字列として取得し、文字列から時刻変換し、書式を指定すればいい。
これを実装する方法がわからない。というか、文字列からdatetime型へ変換するときのパターンが無限にあるだろうことから、網羅できないことが懸念される。スペースひとつ違うだけでエラーになる。また、時刻変換もある。JSTなどからUTCへ変換するなど、異なる時刻体系に変換する方法を調べねばならない。その場合分けも大変そう。
わからないことが多すぎて、めっちゃ大変。そして、自前で実装せねばならないことが多すぎる。ありえない。
タイムゾーン書式%z
は、[+-][0-9]{4}
という書式でないと受け付けない。しばしば、[+-][0-9]{2}:[0-9]{2}
のように時と分の間にコロン:
が入る書式もある。それはエラーになる……。それなのにprint
で表示されるのはコロン付きという謎仕様。
import datetime dt1 = datetime.datetime.strptime('2019-01-01T12:00:00+09:00', '%Y-%m-%dT%H:%M:%S%z') # エラー dt1 = datetime.datetime.strptime('2019-01-01T12:00:00+0900', '%Y-%m-%dT%H:%M:%S%z') # OK print(dt1)
ValueError: time data '2019-01-01T12:00:00+09:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
ちなみに、RSS1.0は:
付きの書式っぽい。
よって、Python3.7より前ではRSS1.0の日時テキストを日付型に変換できない……嘘だろ……。ISO-8601形式チェックすらできないとかクソすぎてクソ。
ただし、Python3.7からは:
に対応するらしい。そんな新しい環境は入っていない……。
Python最新環境をつくる
なら、新しいPython環境を作ったほうが早いと思うだろうが、それこそ超絶に大変。地獄と呼ぶにふさわしい苦行が待っている。
docker,anyenv,pyenv,venvなどの事前設備を整え、さらにPythonビルド前にビルドツール各種の用意をし、Pythonで使うライブラリTk,SQLite3の最新版を用意し、その上でPythonをビルドする。できたら次は必要なパッケージをインストール。これだけ大変なことをするのに、一体どれだけの学習と手間が必要だろうか。たかが日付変換のためにやることではない。
- docker,anyenv,pyenv,venvなどの事前設備を整える(どれを使い使わぬかの判断から)
- ビルドツール各種を用意する
- Pythonで使うライブラリTk,SQLite3の最新版を用意する(自前ビルド)
- パッケージ仮想化環境をつくる(venv)
- Pythonパッケージをインストールする(pip)
- 仮想化環境を有効化する
- パッケージを使ったPythonコードを書く
所感
これだからPythonは嫌い。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- Python 3.5.3
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux