ニコニコ動画 『スナップショット検索 v2 API』 ガイド
これをいじっていたのですが、jsonFilterの形式を指定する際に日付形式で少し大変だったのでメモ。
ISO8601形式で出さないといけないが、 YYYY-MM-DDThh:mm:ss±hh:mm
の形式を満たすためには所謂 Python の時刻の合使いでいうところの aware ではなく naive にしてから isoformat する必要がある。
あまり使いこなせていない感じだったので、調べてみると delta を使って timezone を作ってセットして、それをさらにタイムゾーン付きで入れたり、 replace したり、 astimezone とかでずらせばできるらしい。
isoformat は spec="seconeds"
を引数にすると上記の hh:mm:ss
形式で取ることができる。
このあたりを参考にした
- https://atmarkit.itmedia.co.jp/ait/articles/2111/02/news019.html
- https://stackoverflow.com/questions/7065164/how-to-make-a-datetime-object-aware-not-naive-in-python
- https://kokufu.blogspot.com/2018/12/python-date-datetime.html
- https://note.nkmk.me/python-datetime-pytz-timezone/
使ったのはこの辺のメソッド
- https://docs.python.org/3/library/datetime.html#datetime.datetime.combine
- https://docs.python.org/3/library/datetime.html#datetime.datetime.astimezone
- https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat
出来たものはこんな感じ。APIの性質上、データ追加タイミングが限られるものなので少し検索範囲を長めにとっている。
PAST_DAY = 2 def get_past_days(days: int) -> datetime: tmp = date.today() - timedelta(days=days) return datetime.combine(tmp, time()) def past_day_to_now(days: int) -> Dict[str, Any]: jst = timezone(timedelta(hours=+9), 'JST') past_day = get_past_days(days=days).astimezone(jst) now = datetime.now(tz=jst) result = { "type": "and", "filters": [ { "type": "range", "field": "startTime", "from": past_day.isoformat(timespec="seconds"), "to": now.isoformat(timespec="seconds"), "include_lower": True }, ] } return json.dumps(result)
命名が微妙にな気がするけど一旦動いたのでよしとする。
ちなみに timezone 周りはここ最近よくなったらしいので pytz を使わなくても何とかなるような気もしてきました。