rn_xmlrpc.php を修正し、Windows Live Writer, Open Live Writer から日付指定で投稿した場合に、正常に日付が設定されるよう修正した。

記事は、 metaWeblog::newPost, metaWeblog::editPost で投稿され、投稿日時は dateCreated パラメータで送信される。 rn_xmlrpc.php XML-RPC Server 側でこのパラメータを受信して記事の投稿日時を設定し公開するところまではまずできたが、公開された記事の日時が意図したものより9時間前のものになっていた。

こうなる理由を探していて、下のような記事が見つかった。

どうやら、 XML-RPC specification によると、 XML-RPC API では dateCreated は ISO8601 形式で送信されるが、タイムゾーンは送信されないことになっているらしい。

What timezone should be assumed for the dateTime.iso8601 type? UTC? localtime?

Don't assume a timezone. It should be specified by the server in its documentation what assumptions it makes about timezones.

Windows Live Writer / Open Live Writer の XML-RPC 送信データを覗いてみると、 metaWeblog::newPost, metaWeblog::editPost での記事の送信で dateCreated を付加する場合、 “20181207T12:00” のようにタイムゾーンのない ISO 8601 形式で送信されているのが分かった。どうしてそうなるのか推測してみた。

  1. 例えば、 Windows/Open Live Writer から、タイムゾーンが “Asia/Tokyo” の地域で、2018年12月7日21時00分を投稿日時として記事を送信した場合:
  2. Windows/Open Live Writer は、 “20181207T12:00:00+09:00” のような ISO 8601 形式をつくり、 metaWeblog::newPost で記事を送信する。
  3. metaWeblog::newPost の内部で使用されているXML-RPC API が dateCreated の ISO 8601 形式の日付情報から時差の部分を除去してしまい( “20181207T12:00” になる)、その後、それを送信する。
  4. 結果的に、時差の部分が無くなった UTC での投稿日時が送信される。
  5. 送られてきた dateCreated の日時をブログ側でそのまま表示すると、 UTC での日時なので9時間前になる。

ということだろう。

他の XML-RPC クライアントからも、同じ状況の日時が送信されるのか不明だが、恐らく同じなのではないかと思う。

この推論をもとに、先ほど紹介した一つ目の記事を参考に、WordPress と同様の動作(タイムゾーンが指定されていなければ日付を UTC として扱う)をするように修正した。記事によると、タイムゾーンがついている場合はそのタイムゾーン情報に従って日付を扱うとされているが、 Windows/Open Live Writer で送信した場合タイムゾーンは無くなることと、そもそもそのようにタイムゾーン付きで ISO 8601 形式の dateCreated を送信してくる動作自体が XML-RPC specification に違反する動作なので、現状この処理(=タイムゾーンがついている場合の動作)は実装していない。

とりあえずは、これで問題なく動作していることを確認した。

2018-12-15 : 上の推論の間違いに気づいたので訂正。

Windows/Open Live Writer が、タイムゾーンが “Asia/Tokyo”の地域で、2018年12月7日21時00分を投稿日時として記事を送信した場合、もし最初に UTC からの時差を付けた ISO 8601 形式の日時を作るのであれば、 “20181207T21:00:00+09:00”とするはずなので、これの時差の部分が除去されても、“20181207T21:00:00”となり、これを PHP はローカル時刻と考えるので、9時間前の時刻にはならない。

ところが実際は9時間前の時刻として表示されるということは、 Windiws/Open Live Writer は最初から UTC の時刻を作成し、しかも末尾に“Z”または“+00:00”を付加していない、あるいは、付加しているが XML-RPC API が “Z”を削除して送信している、ということになる。