rn_xmlrpc.php を修正 2018-12-10 (月) 02:43:56+09:00

ソフトウェア

日時指定での投稿時の動作の修正をした。

これまでは、 XML-RPC の規格に沿って、 metaWeblog API newPost, editPost の dateCreated ( ISO 8601 形式)に UTC 、タイムゾーンが付加されずに送信されることを前提に、送信されてきた dateCreated に無条件で “Z” を付加し UTC であることを明示していた。

しかし、

そこで、 ISO 8601 形式のバリデーションの方法を参考にしながら、 rn_xmlrpc.php を対応させた。

現在の動作は、

ISO 8601 形式(基本形式、拡張形式、混在形式)( UTC 、タイムゾーンなし)⇒UTC形式として処理し表示。

ISO 8601 形式(基本形式、拡張形式、混在形式)( UTC またはタイムゾーンあり)⇒タイムゾーンを処理し表示。

となった。

Windows/Open Live Writer が dateCreated に ISO 8601 規約違反の形式(YYYYMMDDThh:mm:ss)で日時を送ってくるので、やむを得ずその形式(混在形式)にも対応させた。


Windows Live Writer および Open Live Writer で、公開日付指定で記事を投稿した際に、 metaWeblog API newPost, editPost で送信されてくる dateCreated ( dateTime.iso8601 ) の形式は:

<member>
  <name>dateCreated</name>
  <value>
    <dateTime.iso8601>20181209T12:00:00</dateTime.iso8601>
  </value>
</member>
<member>
  <name>date_created_gmt</name>
  <value>
    <dateTime.iso8601>20181209T12:00:00</dateTime.iso8601>
  </value>
</member>

のような表記となっている。

しかし、メモに投稿しておいた「ISO 8601 規格について」通り、 ISO 8601 規格では日付の基本形式である[20181209]と時刻の拡張形式である[12:00:00]は混在させてはならないので、この形式は規格に違反している。

日付の形式に合わせるならば、[20181209T120000]とするのが正しい。


ISO 8601 規格について 2018-12-09 (日) 22:40:00+09:00

メモ

下は、JISX0301を参照し、 XML-RPC API の実装のために必要な部分を抜粋したものだが、JISX0301末尾記載の差異を見る限りは ISO 8601 においても同じと考えてよい。

(1)日付の表示形式

基本形式:

  1. YYYYMMDD (例)20181224

拡張形式:

  1. YYYY-MM-DD (例)2018-12-24

(2)時刻の表示形式

基本形式:

  1. hhmmssZ (例)232030

拡張形式:

  1. hh:mm:ss (例)23:20:30

(3)協定世界時(UTC)における時刻の表記

  1. (2)の時刻表示形式の直後にUTCの指示記号[Z]を付加する。(例)232030Z, 20:30:30Z

(4)地方時と協定世界時との差(時差)の表記

地方時の表記の最下位(右端)の直後に間隔をあけず以下の形式で表記する。

基本形式:

  1. (+|-)hhmm (例)+0900, +0730
  2. (+|-)hh (例)+09

拡張形式:

  1. (+|-)hh:mm (例)+09:00, +07:30

(5)日付と時刻の組み合わせの表記

基本形式:

  1. YYYYMMDDThhmmss (例)20181224T123456
  2. YYYYMMDDThhmmssZ(例)20181224T123456Z
  3. YYYYMMDDThhmmss(+|-)hhmm(例)20181224T123456+0900
  4. YYYYMMDDThhmmss(+|-)hh(例)20181224T123456+09

拡張形式:

  1. YYYY-MM-DDThh:mm:ss (例)2018-12-24T12:34:56
  2. YYYY-MM-DDThh:mm:ssZ (例)2018-12-24T12:34:56Z
  3. YYYY-MM-DDThh:mm:ss(+|-)hh:mm (例)2018-12-24T12:34:56+09:00
  4. YYYY-MM-DDThh:mm:ss(+|-)hh (例)2018-12-24T12:34:56+09

(6)注意点

  1. 基本形式と拡張形式は、日時、時刻の組み合わせにおいて、いずれかに統一する、とされているので、混在させてはならない。
  2. 時差については、自国の表記および日時と時刻の組み合わせの表記に含まれているため、結果として、日時、時刻、時差の組み合わせにおいて、基本形式と拡張形式は混在してはならない

rn_xmlrpc.php を修正 2018-12-08 (土) 15:12:00+09:00

ソフトウェア

Windows Live Writer, Open Live Writer で投稿する場合に、 Writer 側で metaWeblog API, Movable Type API の2種類のアカウントで問題なく使用できるように API の処理を修正した。

rNote の現状の課題:

rNote の構造上、カテゴリ=ディレクトリなので、そのままでは複数カテゴリを指定された記事を実現できない。現在は、複数カテゴリを指定された記事を投稿された場合、先頭に指定されたカテゴリのみを採用し、残りは破棄している。(シンボリックリンクのような機能を追加すれば実現可能だが・・・。)

複数カテゴリを持てるようにするには仕様の検討が必要だが、記事の属性を表すために、既にキーワードを実装しており、キーワードは複数の属性を表現できるため、カテゴリまで複数持たす必要性を感じない。カテゴリにせよキーワードにせよ、使い道は単語をキーに記事を検索する用途だと思うので、キーワードが実装され検索できる以上カテゴリ複数化はしなくていい気がする。

Windows/Open Live Writer の現状の課題:

やはり追記を書く機能がないこと。 Open Live Writer のソースを読むと内部的には mt_text_more を処理しているので、追記をユーザーインターフェースを追加すればよさそう。画面上の部品のレイアウト変更・部品追加と、ブラウザコントロールの追加管理を実装する必要があるので、ちょっと面倒そう。画面上の構成としては Blog Write のとっている形が一番自然でよいと思う。


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”を削除して送信している、ということになる。