やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Pythonにおける日付変換の罠(ISO8601)

 3.7からfromisoformatが使える。が、タイムゾーン:がないとエラーになるなどISO8601互換とはいえない中途半端さ。これでは罠になってしまうだろう。┐(´д`)┌ヤレヤレ

コード

import datetime
>>> datetime.datetime.fromisoformat('2000-01-01T00:00:00+09:00')
datetime.datetime(2000, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400)))
>>> datetime.datetime.isoformat(datetime.datetime(2000, 1, 1, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=32400))))
'2000-01-01T00:00:00+09:00'

注意

タイムゾーンには:が必要

 ISO8601では:がなくてもよい。だが、fromisoformat:がないとエラーになる。

>>> datetime.datetime.fromisoformat('2000-01-01T00:00:00+0900')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Invalid isoformat string: '2000-01-01T00:00:00+0900'

 クソ。ISO8601に対応したようにみせかけて中途半端な実装である。さすがPythonクオリティ。信用できなさにおいては随一。

公式の説明

ご用心 このメソッドは任意の ISO 8601 文字列の構文解析をサポートしてはいません - このメソッドは datetime.isoformat() の逆操作をするためだけのものです。 より高機能な ISO 8601 構文解析器である dateutil.parser.isoparse が、サードパーティーパッケージの dateutil から利用可能です。

 「ご用心」じゃねーだろ。ちゃんと実装してくれや。「より高機能」ではなく正しく仕様を実装してあるだけだろ。

罠:このメソッドはISO8601互換ではありません。YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]の書式のみをサポートしています。たとえばISO8601にはタイムゾーンに:がない書式などもサポートしておりますが、このメソッドでは先述の書式しか解析できません。

 だったらisoの文字を使うなよ。usoだろ。usoに改名しろ。

datetime.datetime.from_uso()
datetime.datetime.uso()

 formatの文字はいらないだろ。なにせISO8601の書式仕様にちゃんと対応してないんだから。さも書式に対応しているかのように名乗ってんじゃねーぞホラ吹きが。

 kusoでもいい。これこそふさわしい名前だろ。

datetime.datetime.from_kuso()
datetime.datetime.kuso()

 datetime.datetime.fromisoformat。このふざけた名前はなんなんだよ。長すぎるだろ。ヘビかよ。ウソだしクソだしトグロまいてるし。ひどすぎるよ。

 あとさ、スネークケースじゃないんだけど? from_iso_formatじゃないのかよ。命名規則も適当すぎる。やる気あんのか。もうヘビですらない。ちゃんとスネークしろや。同一性をもてない、もとうとしない。何者にもなれないカス。ヘビを名乗るゴミ。それがPtython。

対象環境

$ uname -a
Linux raspberrypi 5.10.52-v7l+ #1441 SMP Tue Aug 3 18:11:56 BST 2021 armv7l GNU/Linux