Template‐ノート:Checkdate
defaultdate指定の動作について
[編集]- defaultdateを指定し「yyyy-m」「yyyy-mm」形式で入力すると、一部で正しい形式でもdefaultdateが返されるようになったのですが、これは仕様でしょうか。おそらく8月12-14日あたりの変更からのように思います。いま少し確認したところ、2013-5, 2013-6, 2013-7, 2013-8で確認しています。
- {{Checkdate|2013-5|defaultdate=エラー}}→エラー
- 素人ゆえソースを見ても原因が分からないので、だれか対処をお願いできますでしょうか?--0nedream(会話) 2013年8月28日 (水) 10:38 (UTC)(修正:0nedream(会話) 2013年10月14日 (月) 11:51 (UTC))
- こんにちは、リョリョと申します。私は仕様に詳しくありませんので対処などはできませんが、利用者‐会話:しまあじ#「yyyy-m」が機能しなくなった?と、Template‐ノート:複数の問題#旧仕様形式で記入されている日付を現仕様形式へ置換するBot作業依頼提案あたりに関連する事項じゃないかと推察いたします。--リョリョ 2013年8月28日 (水) 10:56 (UTC)
- リョリョさんのご指摘の通り、一時的な暫定対処です。事情についてはこちらをご参照ください。そのページは用が済み次第に当テンプレートからの呼び出しを打ち切り、廃止する予定ですので、内部リンクでなくアドレス直接指定で記させていただきます。私自身が、その問題と関係する問題ではありながら別の問題の対処を優先していて、そちらの議論のお返事をいったん保留にしておりまして失礼しております。なお、解説ページへの追記、ありがとうございました。簡単に一言で言ってしまうと「年月とも時間ともどちらにも解釈できる値が指定された場合に、当{{Checkdate}}としては{{#time}}に「年月」としての解釈を優先するか、もしくは「どちらなのか判断できない」というエラーを返して欲しかったのに、実は「時間」としての解釈を優先していた」ということですね。--しまあじ(会話) 2013年8月28日 (水) 11:11 (UTC)
- なるほど、そのようなご事情があったのですね。すみませんお騒がせしました。--0nedream(会話) 2013年8月28日 (水) 12:43 (UTC)
- つい先日のテンプレート改訂に伴い不要になった内部テンプレートを削除依頼に出したいのですが、上に旧版テンプレートのソースが展開されている中で、その削除したい内部テンプレートが呼び出されており、そのまま削除すると上に例示されている部分の表示が異常になりますのでコメントアウト的な処置をさせていただければと思うのですが、よろしいでしょうか。--しまあじ(会話) 2013年10月13日 (日) 14:28 (UTC)
- ご連絡ありがとうございます。とりあえず、異常な表示にならないよう代替しておきました。--0nedream(会話) 2013年10月14日 (月) 11:51 (UTC)
- つい先日のテンプレート改訂に伴い不要になった内部テンプレートを削除依頼に出したいのですが、上に旧版テンプレートのソースが展開されている中で、その削除したい内部テンプレートが呼び出されており、そのまま削除すると上に例示されている部分の表示が異常になりますのでコメントアウト的な処置をさせていただければと思うのですが、よろしいでしょうか。--しまあじ(会話) 2013年10月13日 (日) 14:28 (UTC)
- なるほど、そのようなご事情があったのですね。すみませんお騒がせしました。--0nedream(会話) 2013年8月28日 (水) 12:43 (UTC)
- リョリョさんのご指摘の通り、一時的な暫定対処です。事情についてはこちらをご参照ください。そのページは用が済み次第に当テンプレートからの呼び出しを打ち切り、廃止する予定ですので、内部リンクでなくアドレス直接指定で記させていただきます。私自身が、その問題と関係する問題ではありながら別の問題の対処を優先していて、そちらの議論のお返事をいったん保留にしておりまして失礼しております。なお、解説ページへの追記、ありがとうございました。簡単に一言で言ってしまうと「年月とも時間ともどちらにも解釈できる値が指定された場合に、当{{Checkdate}}としては{{#time}}に「年月」としての解釈を優先するか、もしくは「どちらなのか判断できない」というエラーを返して欲しかったのに、実は「時間」としての解釈を優先していた」ということですね。--しまあじ(会話) 2013年8月28日 (水) 11:11 (UTC)
- こんにちは、リョリョと申します。私は仕様に詳しくありませんので対処などはできませんが、利用者‐会話:しまあじ#「yyyy-m」が機能しなくなった?と、Template‐ノート:複数の問題#旧仕様形式で記入されている日付を現仕様形式へ置換するBot作業依頼提案あたりに関連する事項じゃないかと推察いたします。--リョリョ 2013年8月28日 (水) 10:56 (UTC)
テンプレートの修正について
[編集]テンプレートを整理・修正してみました。「Template:Checkdate/sandbox」に試験的にアップロードしていますので、問題等あればご指摘ください。
既存のテンプレートにあったisoという引数は将来の予備的なものということですので、とりあえず省いています。見たところ、特定条件下のときに入力テキストをそのまま出力させるためのフラグのようですが、もし必要があればまた加えてください。修正版の方では、代わりに(というわけでもないですが)出力の書式を任意指定する引数formを新たに加えています。年だけや月だけ、あるいは比較演算などで扱いやすい数字列("yyyymm"みたいな)で出力するといった使用法を想定しています。この引数に"form={{{1}}}"と入力した場合、日付パラメータとしてのエラーチェックだけ行い、dateの入力テキストを元のまま出力します(ただし"yyyy年m月"形式での入力には対応しません)。
その他、処理の変更点は、以下のとおりです。
- 対応する入力書式
- 基本的に#time関数がサポートする入力書式全般に対応。"yyyy Month"(2013 sep)と"d Month yyyy"(22 Sep 2013)にも対応。
- 年・月の値入力の有無でエラーチェックを行い、年数と月数が入力されていないもの(正常に認識されないものを含む)をエラーとしてはねます。この新方式のエラー入力チェックの方法により、入力書式の汎用性を高めました。
- ただし、"Month yyyy"(sep 2013)や"yyyy d Month"(2013 22 sep)の形式は非対応で、エラー扱いとなります。理由は、年の値の入力チェックに判定式の追加が必要になるので(たいした式ではないのですが最初の判定式の段階で#time関数を2回呼び出す必要があって若干ながら無駄かなと)、実用性と費用対効果の面を考えて省略しました。…と最初は思ったのですが、現在すでにサポートされている入寮形式でしたので、"Month yyyy"形式の入力にも対応しました。--2013年9月24日 (火) 12:48 (UTC)
- 入力可能な書式を従来型の書式(yyyy年m月~, yyyy-m~)だけに限定する必要がもしあれば、
- " {{#iferror:{{#time:|{{{1}}} 1/1}}|{{{1}}}|false}} " の条件式を
- " {{#ifeq:{{padleft:|5|{{{1}}} }}|{{#expr:abs{{padleft:|4|{{{1}}} }} }}-|{{{1}}}|false}} " に変更すればいちおう可能です。
- "yyyy年m月"でなく"yyyy-m月"のような入力値については、従来どおり"yyyy年m月"形式に変換せずそのままの出力となります。引数1の6or7文字目が"月"の文字かどうかを判定してtrueなら引数1をその直前でぶった切ってから#timeに代入すればいいだけなので技術的に難しい処理ではないですが、ニーズ低そうな気がしたので、式の軽量化のためその処理は省きました。もし需要があれば、いちおう対応は可能です。
- 入力年の範囲
- 年の入力可能範囲は、2500年まで(下限は設定無し)に変更。従来の範囲2000~2099年より拡張。
- ちなみにこの2500年という入力上限値は、年の値が未入力かどうかのエラーチェックをする判定式に使用しています。2500という数字自体は実用上問題ない範囲で適当に設定しただけなので、時刻のパラメータとみなされない4桁の数字列(上2桁が25以上、もしくは下2桁が60以上の値)であればどんな値でも構いません。たとえば上限を2900年までにしても構いませんし、逆に下限を0060年などに設定すれば、上限値の設定は必要ありません。
しばらく待って問題なさそうなら反映したいと思います。--ディー・エム(会話) 2013年9月23日 (月) 14:03 (UTC)
- 報告「Template:Checkdate/sandbox」を少し修正しました。直近の変更点としては
- "Y年n月~~" と "Y-n(m)~~" 以外の場合の年数上限を2059年までに制限。"Month, Y" 形式(日が未入力の場合)の月末日処理が不正確となるため。レアケースのために処理を増やしたくないので、"Month Y" や "j Month Y" なども一律に制限。
- 入力値のチェックを軽減するため、"Y年n月~~" と "Y-n(m)~~" 以外は時刻の入力不可に。"yyyy-n(m)~~" で入力された場合の#timeの実行を
1回で済ませる(それ以外の場合も2回に軽減)。(再変更し、#timeの実行は2回) - オプションの出力書式(引数form)が空文字列のとき値の出力をキャンセル、エラーチェックのみ実行。
- 主にそんな感じです。汎用性をある程度割り切ってちょこちょこシェイプアップしてみましたが、この改訂版の方の効率改善はこのあたりでほぼ限界に近いと思います。--ディー・エム(会話) 2013年10月6日 (日) 13:40 (UTC)
- 報告「Template:Checkdate/sandbox」を少し修正しました。直近の変更点としては
- まず「Template:Checkdate/testcases」でご確認お願いします。サンドボックスのテストについてはコメントアウトしてあったのを表示させました。ページの上半分がサンドボックスのテスト、下半分が現状でのリリース版のテストです。原因についてはまだ未確認ですが、「yyyy-mm-dd」形式と「Month yyyy」形式について、ちょっと「?」な部分があります。--しまあじ(会話) 2013年9月23日 (月) 14:28 (UTC)
- testcasesのご対応とご報告ありがとうございます。「yyyy-mm-dd」形式のほうは式のタイプミスでした。すみません。「Month yyyy」形式のほうは、上にもちょっと書きましたが、実は非対応な仕様なのです…しかしテスト結果を見ると未来の年数だけ出力されているようで、いっそ対応させた方が良いのかも。--ディー・エム(会話) 2013年9月23日 (月) 15:38 (UTC)
- 「Month yyyy」形式に対応させないと、どういうことになるかと申しますと、英語版からの翻訳記事において、そのタグの日付が英語版形式で記されていた場合に、その日付を日本語形式に書き変えないと、管理カテゴリの収まるべきところに収まらなくなるのです。その日付書き変えを不要にするために付加した機能です。私はテンプレートのロジックの中身については、あくまで「手段」として二の次で、実際の各記事で発生している問題の対処として付加した機能です。--しまあじ(会話) 2013年9月23日 (月) 17:01 (UTC) + 細かく言うと、私が付加したというより、私が手を入れる前の元々からサポートされていたので、その仕様を残したのです。--しまあじ(会話) 2013年9月23日 (月) 17:07 (UTC) ← この経緯については複雑で、この説明では不十分で、これまでの経緯についてご存じでないかたに対しては誤解が発生してしまうかもしれないのですが、この場では詳細な経緯については省略させていただきます。--しまあじ(会話) 2013年9月23日 (月) 17:38 (UTC)
- testcasesのご対応とご報告ありがとうございます。「yyyy-mm-dd」形式のほうは式のタイプミスでした。すみません。「Month yyyy」形式のほうは、上にもちょっと書きましたが、実は非対応な仕様なのです…しかしテスト結果を見ると未来の年数だけ出力されているようで、いっそ対応させた方が良いのかも。--ディー・エム(会話) 2013年9月23日 (月) 15:38 (UTC)
- いま、テストケースをボーっと眺めていてたまたま発見したのですが、たとえば「2000-02-30」等と指定された場合に、2月30日という日付は存在しないので、現状リリース版では基本的には何も返さない(エラー扱い)としているのですが、サンドボックスでは翌月に繰り上がっています。これは回避しないと、ちょっと問題があるのです。その問題を回避するために、現状では何も返さないようエラー扱いとしています。--しまあじ(会話) 2013年9月23日 (月) 20:18 (UTC)
- それは一般的な日付系の関数で共通の仕様だと思いますのでそのままが良いというのが個人的意見ですが、どうしても必要であれば(#time関数の呼び出しがもう一回必要ですが)、対処は可能です。エラー出力もできると思いますが、"2月"で出力するほうが式は簡単にいけます、たぶん。--ディー・エム(会話) 2013年9月24日 (火) 03:35 (UTC)
- なぜそれに問題が発生するのかは、テンプレート内だけを見ていてはわからないと思うのですが、各記事において、そういう記入がされているケースがどういう場合なのかを観察していただけるとわかっていただけるかも、と思うのですが(そういう観察をしているのは、もしかしたら私だけかも?とも思ったりするのですが)、この場では省略します。ちなみに、2月だけに限らず、小の月(30日までしかない月、つまり4月6月9月11月)も含めてです。あと、お返事いただけていませんが、「Month yyyy」対応が必要か否かについては、いかがでしょうか。--しまあじ(会話) 2013年9月24日 (火) 11:37 (UTC)
- いやいやいや、やっぱりその仕様は変ですって。そのオーダーに対応するとしたら、現在のテンプレートでサポートしている " yyyy-m-d " 形式に限れば " {{#ifexpr:{{pad left:|5|{{{1}}} }}({{padleft:|7|{{{1}}}- }}.0)={{#time:m|{{{1}}} }} | true |false }} " の条件式で検出はやろうと思えばできなくはないですが、わざわざ式を追加して#timeの実装機能をエラー扱いで殺すのは、対処としてさすがに不合理なので。もし呼び出し元のテンプレートの中にそれで不具合が起こるものがあるようなら、そっちを修正するほうが良いと思います。でないと、両方のテンプレートでお互いに非効率な処理をやり合って肥大化してしまう、ということにもなりかねないですし。もし具体的に不具合のケースがあればお教えください。
- 「Month yyyy」のほうは現在も出力対応していたのですね。すみません、勘違いしてました。取り急ぎ対応しました。代償として時刻入力が不可となってしまうのと最初の条件式で#timeを2回使うのが若干しのびないですが、これなら処理自体さほど増やさずに済むので、許容範囲でしょう。--ディー・エム(会話) 2013年9月24日 (火) 12:48 (UTC)
- なぜそれに問題が発生するのかは、テンプレート内だけを見ていてはわからないと思うのですが、各記事において、そういう記入がされているケースがどういう場合なのかを観察していただけるとわかっていただけるかも、と思うのですが(そういう観察をしているのは、もしかしたら私だけかも?とも思ったりするのですが)、この場では省略します。ちなみに、2月だけに限らず、小の月(30日までしかない月、つまり4月6月9月11月)も含めてです。あと、お返事いただけていませんが、「Month yyyy」対応が必要か否かについては、いかがでしょうか。--しまあじ(会話) 2013年9月24日 (火) 11:37 (UTC)
- それは一般的な日付系の関数で共通の仕様だと思いますのでそのままが良いというのが個人的意見ですが、どうしても必要であれば(#time関数の呼び出しがもう一回必要ですが)、対処は可能です。エラー出力もできると思いますが、"2月"で出力するほうが式は簡単にいけます、たぶん。--ディー・エム(会話) 2013年9月24日 (火) 03:35 (UTC)
- いま、テストケースをボーっと眺めていてたまたま発見したのですが、たとえば「2000-02-30」等と指定された場合に、2月30日という日付は存在しないので、現状リリース版では基本的には何も返さない(エラー扱い)としているのですが、サンドボックスでは翌月に繰り上がっています。これは回避しないと、ちょっと問題があるのです。その問題を回避するために、現状では何も返さないようエラー扱いとしています。--しまあじ(会話) 2013年9月23日 (月) 20:18 (UTC)
- {{複数の問題}}のノートのかつての古い議論、「Template‐ノート:複数の問題#このテンプレートは使用すべきではないのでしょうか?」の、特にその中においての、私しまあじと、Frozen-mikanさんのやりとりの部分を、よーく読んでみてください。このテンプレートは、元々のルーツは、汎用テンプレートではないのです。ですから、日付時刻の足し算や引き算などに対応させる必要は無いし、それに対応させるとかえって、記入ミスを記入ミスとして検出できなくなるケースが増えるというデメリットとなるだけなのです。はっきり言ってしまいますと、このテンプレートは元々、{{複数の問題}}でしか使われていなかったローカル内部テンプレートだったのです。そんなローカルな内部テンプレートを安易に他のテンプレートに転用したのか?という疑問も持たれるかと思いますが、現在の日本語版における{{Checkdate}}は、元々のルーツは英語版{{Checkdate}}でありながらも、それとアッパーコンパチをできるだけ維持しつつ、ただし日本語版にとっては不都合な記入形式への対応だけは省いたものでして、実は、現状の{{Checkdate}}の原型は、すでに廃止してあるテンプレート、{{
翻訳コンニャク}}・・・じゃなくって{{年月翻訳}}なのでして、{{複数の問題}}ではない他の単独テンプレートには、その{{年月翻訳}}を使用していたのです。それを{{Checkdate}}に統合して廃止した、という経緯であるため、現状のような状態となっているわけです。--しまあじ(会話) 2013年9月25日 (水) 12:00 (UTC)- いえ、というか根本的に、仮にこのテンプレートの用途を限定するにしてもしなくても、今のアルゴリズムは非効率なのでその修正です(さらにちょっと整形しました[1])。現行の出力機能は全てカバーしつつ効率化したら、ついでに汎用性が向上しただけで。何か不具合があれば具体的にご指摘ください(ここまでのデバッグの多大なご配慮、ご尽力に感謝しております。今後ともよろしくお願いします。)。--ディー・エム(会話) 2013年9月25日 (水) 14:48 (UTC)
- 懸念事項がいくつかあるのですが、それらをいっぺんに書くと、ご確認いただくのが大変になると思いますので、一点ずつご確認いただき、それが済んでから、次の懸念事項についてに進ませていただこうと思います。まず、すでに{{複数の問題}}のノートにも記してある件なのですが、この{{Checkdate}}が呼び出されている記事のうち、{{#time}}の呼び出しを必要としている記事は、その呼び出しを必要としない記事に比較して、かなり少数なのです。たとえば、直近の 1年間については、大雑把に申しますと、私が「yyyy-m」形式を「yyyy年m月(+日時)」に書き変える前の状態で、目安として 1割くらいだった、と思ってください。たとえば「Category:出典を必要とする記事/2012年m月」の、ある月に分類されている記事が約1,000記事だったとしたら「yyyy-m」形式で記入されていたのは、だいたい 100記事くらい、というかんじです。その他は全て「yyyy年m月(+日時)」形式です(余談ですが、元々「yyyy-m」形式をサポートしていなかったテンプレートに対して「yyyy-m」形式で日付を記入していたのは、ごく一部の利用者さんだけだった、という発見もありました)。その比率の差は、古い日付ほどさらに大きくなっているはずであり、特に2010年以前の日付については、「yyyy-m」形式で日付が記入されているのは{{複数の問題}}のみであり、他の問題指摘用テンプレートにおいては、翻訳記事における「Month yyyy」などの例外を除いて、全て「yyyy年m月」形式で記入されています。そういうわけで、これまで「yyyy年m月」形式のほうを優先させていたのですが、「yyyy-mm(-dd)」形式のほうを優先させるようにしてしまうと、かえって効率が悪くなってしまう記事のほうが圧倒的に多いのです。まず、この点についてはいかがでしょうか。--しまあじ(会話) 2013年9月26日 (木) 00:30 (UTC)誤字訂正--しまあじ(会話) 2015年7月26日 (日) 16:09 (UTC)
- いえ、というか根本的に、仮にこのテンプレートの用途を限定するにしてもしなくても、今のアルゴリズムは非効率なのでその修正です(さらにちょっと整形しました[1])。現行の出力機能は全てカバーしつつ効率化したら、ついでに汎用性が向上しただけで。何か不具合があれば具体的にご指摘ください(ここまでのデバッグの多大なご配慮、ご尽力に感謝しております。今後ともよろしくお願いします。)。--ディー・エム(会話) 2013年9月25日 (水) 14:48 (UTC)
- {{複数の問題}}のノートのかつての古い議論、「Template‐ノート:複数の問題#このテンプレートは使用すべきではないのでしょうか?」の、特にその中においての、私しまあじと、Frozen-mikanさんのやりとりの部分を、よーく読んでみてください。このテンプレートは、元々のルーツは、汎用テンプレートではないのです。ですから、日付時刻の足し算や引き算などに対応させる必要は無いし、それに対応させるとかえって、記入ミスを記入ミスとして検出できなくなるケースが増えるというデメリットとなるだけなのです。はっきり言ってしまいますと、このテンプレートは元々、{{複数の問題}}でしか使われていなかったローカル内部テンプレートだったのです。そんなローカルな内部テンプレートを安易に他のテンプレートに転用したのか?という疑問も持たれるかと思いますが、現在の日本語版における{{Checkdate}}は、元々のルーツは英語版{{Checkdate}}でありながらも、それとアッパーコンパチをできるだけ維持しつつ、ただし日本語版にとっては不都合な記入形式への対応だけは省いたものでして、実は、現状の{{Checkdate}}の原型は、すでに廃止してあるテンプレート、{{
(インデント戻します。)了解です。ひとつずつ返答したいと思います。
- ユーザーの入力傾向についての概観
- 私自身もこの前からTemplate:要出典を貼ったときに "yyyy-m-d" 形式を使ってました。ゆくゆくを考えたら今からそっちを普及していった方が良いなと考えて意図的な判断だったのですが、その時は「Template‐ノート:複数の問題」で揉めてるのを知らなかったので、とりあえずはその結論が出るまではその問題に関しては様子を見るしかないのかなと、ひとまず静観の構えです。"yyyy年m月"で入力された文字列をほぼそのまま"yyyy年m月"で出力するという仕様はそのテンプレート内だけみると簡易な処理だけですむので一見好都合なように感じてしまいますが、結局呼び出し元のテンプレートの方にそのしわ寄せがいっているだけで、テンプレート間全体の連携をみると "yyyy年m月"形式での文字列処理が結局大きな負担になっているのが現実ですよね。そこの解消がとりあえずの目標というか、この問題のひとまずのゴールかなと考えています。
- 逆にミクロな視点で眺めても、話を単純化するためにひとまずこのテンプレート呼び出しの負荷だけに注目するとして、呼び出し数7万件のテンプレートのソーステキスト転送量の削減効果は軽視できないと思いますし、"yyyy年m月"以外の入力が仮に1割程度だったとしても、呼び出し7万件の1割は7千件ですから、そのケースに対する処理効率の向上対策も相応に価値がある改良だと考えています。ただ、"yyyy年m月"入力が大多数の現時点では"yyyy年m月"への最適化を最優先する方が効率的というご指摘はそのとおりだと思います。そう思いつつトータルで損はしてないだろうという判断の下に条件分岐の順番をひっくり返したのですが、処理の優先順位についてはひとまず現状と同じ"yyyy年m月"優先に変更しました。
- 「yyyy-mm(-dd)」形式の処理の効率について
- 現在のアルゴリズムでは「yyyy-mm(-dd)」入力の場合の非効率が顕著ですが、改良型のほうは処理の順序変更も比較的容易で、移行さえしてしまえれば "yyyy-m" 入力の使用割合が1割でも2割でもその使用率が増えたら増えた分だけ全体の効率が向上するので、損をすることはないですし。
--ディー・エム(会話) 2013年9月26日 (木) 15:59 (UTC)
- ありがとうございました。その後のサンドへボックスに追加なされた修正も拝見しましたところ、前記の件についてだけでなく、次にご確認いただこうと予定していた件に影響する修正も含まれていましたので、その件についての対処がなされていれば OKであるはずなのですが、もういちど再確認しているところです。あと、当テンプレートがどういう目的で使用されているかという点でいうと、そもそも、{{#time}}は使わないで済ませられるなら、使わないにこしたことはなく、{{#time}}の代わりのコーディングとしては 従来だったら {{#switch}}や {{#if}}の連続、というようなスマートでない方法しか無かったのですが、現在では、それの代わりの方法があります。いま、そちらも調べているところです。--しまあじ(会話) 2013年9月28日 (土) 20:32 (UTC)
- 日付を解析するモジュールの例ができあがったのでお知らせします。{{ISO dateJA}}と{{Checkdate}}の代わりになるものをそれぞれ、利用者:Burthsceh/サンドボックス/モジュール:TimestampFormatter(テストケースのソース、特別:テンプレートサンドボックス)と利用者:Burthsceh/サンドボックス/モジュール:Checkdate(特別:テンプレートサンドボックス(Template:Checkdateの呼び出しが利用者:Burthsceh/サンドボックス/Template:Checkdateの呼び出しになっています。若干速いようです。))に置いています。TimestampFormatterは要るかもしれないものは実装するようにしました。--Burthsceh(会話) 2013年9月29日 (日) 10:41 (UTC)
- 現状リリース版では対処していた点で、ディー・エムさんによる サンドボックスには入っていないので、大丈夫かなと確認していた件なのですが、「Template‐ノート:複数の問題#このテンプレートは使用すべきではないのでしょうか?」の先頭のほうにありますとおり、たとえば {{#time:Y年F|2011-2}}というように 「日」の指定が無い場合に、かつてはその既定値として、閲覧当日の「日」が適用されてしまい(たとえば 本日2013年9月29日を例にすると、「2011-2」は「2011-2-29」と解釈されていた)、その結果として、「日」の指定が無い小の月の「yyyy-m」形式および「Month yyyy」形式は、大の月の月末には翌月に繰り上がる、という現象がありました。そのためにどういう問題が発生していたかというと、月末と月初に、その当該記事が、年月分類カテゴリの 2つの月のサブカテゴリの間を「行ったり来たり」勝手に引っ越していたのです。その問題を対処するため、現状リリース版では、「日」の指定の有無に関わらず、もし指定されていても無視して全て「1日」固定にしていたのですが、本日になって確認しましたら、現在の {{#time}}では「日」の指定が無い場合の規定値は「1日」になっているらしく「2011-2」は「2011-2-1」と解釈されるようです[2]。そうであるとすると、これまで当テンプレート内部でわざわざ「1日」固定にしていた処置は不要になる、ということになりそうです。
- Burthscehさんによるサンドボックスを直接に呼び出そうとしてみたのですが、なぜかちょっとうまくいかなかったので、それをいったん私の個人的サンドボックスにコピーさせていただき(内容は全く同じです)[3]、それを「Template:Checkdate/testcases」に追加しましたので、ご確認をお願います。Burthscehさんご自身のサンドボックスを直接に呼び出すよう修正していただけますと助かります。また、仕様についてもご確認いただきたい点がいくつかあります。よろしくお願いいたします。
- --しまあじ(会話) 2013年9月29日 (日) 13:28 (UTC)
- コメントcurrentdayによる日付補填の件、私が数ヶ月前に#timeの挙動をちょこちょこ調べ始めた頃に確かにあったように思います。当初は{{#ifexpr:{{#time:j|{{{1}}} }}>28| -3 days}}(日付が28日以降なら3日前に補正する)という処理も用意していたのですが、日付を強制補正するという副作用もあり、結局使わずじまいとなりました(それ以外にもパラメータ処理の優先順位も微妙に変わった感じです)。現在は年と日が未入力、もしくは月と日が未入力の場合のみに限定されているようなので、もし今後使うことがあればその入力パターンさえブロックすればOKです。ご参考まで。--ディー・エム(会話) 2013年9月29日 (日) 14:11 (UTC) (以前書いたソースのメモを今見返してみると、この式ちゃんと動作しないですね。補正後の日付で判定しても無駄でした……--ディー・エム(会話) 2013年9月29日 (日) 14:57 (UTC))
- コメントダウンロードしてあるPHP 5.4.14のソース(ext/date/lib/parse_date.re)を見てみると(gnudateshorterで(datenoday・datenodayrevも))日(s->time->d)が1にセットされるようになっています。指定が不要になることで間違いないと思います。{{#invoke:}}は、特別:テンプレートサンドボックスなどを使わない限り、モジュール名前空間にあるページしか呼び出さないので、それ以外の名前空間にあるページを直接呼ぼうすると必ずエラーが発生します。特別:テンプレートサンドボックスを使うようにしてください。利用者:Burthsceh/サンドボックス/モジュール:CheckdateをY年n月以前・Y年m月以後・Y-m月などに対応させる必要があれば単にtに追加するだけで済みます。--Burthsceh(会話) 2013年9月29日 (日) 16:20 (UTC)
- Burthscehさん、「以前」「以後」の文字には対応していただかなくても大丈夫です。というより、対応させてしまうと逆にトラブルが発生します。現状リリース版でもその対応は廃止しており、「以前」については、日・時と同様に単純に切り捨てるようになっています。
- かつては、その対応を {{年月翻訳}}で行っていたため、テストケースに残っているのはその当時の名残であり、その機能については現在では別のテンプレートで行っています。対応させるためではなく全く逆に、かつて対応させていたその機能が正常に廃止できたかどうかを確認するためにテストケースに残してあっただけなのです。よろしくお願いします。--しまあじ(会話) 2013年10月2日 (水) 13:25 (UTC)
- 修正しました。--Burthsceh(会話) 2013年10月5日 (土) 16:38 (UTC)
- 日本語の日付入力をダイレクトに処理できれば関連テンプレート整理の見通しが相当楽になると思います。
- そこで可能であればのお願いなのですが、年数のみ、月数のみ出力することはできないでしょうか?テンプレートは別個で良いので。--ディー・エム(会話) 2013年10月2日 (水) 14:09 (UTC)
- 可能です。--Burthsceh(会話) 2013年10月5日 (土) 16:38 (UTC)
これからどうするか決めたいと思います。
- 現在のTemplate:Checkdate、2013年8月上旬までのTemplate:Checkdate、Template:Checkdate/testcases、利用者:Burthsceh/サンドボックス/モジュール:Checkdateのうちどれを使うようにしますか。Template:Checkdate、Template:Checkdate/testcases、利用者:Burthsceh/サンドボックス/モジュール:Checkdateの速さはそれほど変わらないようです。利用者:Burthsceh/サンドボックス/モジュール:Checkdateの欠点には、Y年n月(yyyy年M月)やY年n月j日 (D) H:i (T)(yyyy年M月d日 (ddd) HH:mm (\U\TC))の書式の日付の処理がTemplate:Checkdate、Template:Checkdate/testcasesに比べて遅いかもしれないこと、モジュール全てにあてはまることですがウィキメディア財団のウィキではLuaSandboxを使ったりキャッシュがよく効いていたりして速いですが、そうでない環境ではオーバーヘッドで遅くなることがあります。
- 対応する書式はどうしますか。Y年n月(yyyy年M月)、Y年n月j日 (D) H:i (T)(yyyy年M月d日 (ddd) HH:mm (\U\TC))などには必ず対応することになると思います。それ以外の書式とどのくらい妥当な日付かどうかチェックするかについてコメントをお願いします。--Burthsceh(会話) 2013年10月5日 (土) 16:38 (UTC)
- コメント(1について)"Y年n月" 形式での入力に関しては、現在のCheckdateと私の改訂案のやつは事実上なんの処理もせずにそのまま出力しているだけなので、プロセス内で入力値の整合チェックと整形まで完結しているモジュール:Checkdateより早いのはある意味当然で、そこの処理速度は必ずしも優劣の判断材料にはならないと思います。呼び出し側のテンプレートで年数や月数の不正な入力値に対応する必要がないというメリットがあるので、使い勝手の面ではモジュール:Checkdateが一番良いように思います。
- ただ、出力形式が文字列としてしか扱えない "Y年n月" の一択だとその処理のメリットを享受し難い面もあるので、上でもちょっと書きましたが、月数のみを抽出して出力できるツールがあれば非常に強力でありがたいです。年月(日)を含めた日付計算にはTimestampFormatterがかなり使えると思いますが、月数のみを取り出したい場合にTimestampFormatterで算出するとなると、子テンプレートに値を持ち出さないかぎり{{#expr:Ym-Y*100}}の計算式内でモジュールを2回呼び出す必要があるのと、年を書き出して消す処理が無駄というかもったいない気がするので。 "Y年n月" からだと文字列の一致判定を羅列する以外に方法がないのでさらに大変で。
- 年の値を出力するテンプレートも必要になる予定があるのですが、基本的には先頭4文字の4桁整数を取り出してイレギュラーなレアケースだけ#time関数で出力すれば良いだけなので普通の条件式等だけで作ったほうが手っ取り早いかもしれません。
- (2について)元号表記の日付は省いて良いかと思います。--ディー・エム(会話) 2013年10月6日 (日) 13:44 (UTC)
- 私としては、Luaモジュールの導入には賛成なのですが、全ての部分を移植するのではなく、現状の先頭の「yyyy年m月」形式対応部分は、モジュールを呼び出さず、できるだけスルーさせ、{{#time}}に依存している部分のみを Luaに移行させてはどうかと思います。
- 上で私が、「yyyy-m」形式で記入されている記事の数は大雑把にいうと目安として 1割くらいだったという意味のことを書きましたが、「使用箇所の多いテンプレート」の「2013年9月10日 (火) 16:59 に最終更新されたキャッシュ」による数値で、できるだけ正確な比率を再確認しましたので、いちおう記しておきます。
- テストケースやノートページに使われている等の例外も含めてですが、主に、問題指摘用の各テンプレートを通して当{{Checkdate}}が呼び出されている記事数は、 100,282ページ。その中で「yyyy年m月」でない形式で記入されているページの数は次の通りです(ひとつのページ内に異なる形式で複数の記入がある場合の重複も含みます)。
- 「yyyy-m」形式で記入されているもの: 5,757ページ(約 5.7%)← 2010年以前からの{{複数の問題}}が中心。他のテンプレートにも使われだしたのは2011年以後。
- 「yyyy-mm-dd」形式で記入されているもの: 1,248ページ(約 1.2%)
- 「Month yyyy」形式で記入されているもの: 1,889ページ(約 1.9%)
- やはり、大雑把にいっても少なくとも 90,000ページ以上は「yyyy年m月(+ 日・時も含む)」で記入されています。当{{Checkdate}}は元々、年月分類カテゴリのサブカテゴリが「yyyy年m月」形式なのに、そうでない形式で記入された日付を「yyyy年m月」形式に変換するためのものです。ですから変換の必要の無い「yyyy年m月」形式を最優先させ、できるだけスルーさせるようにしています。それに対してのレスポンスは第一に優先させていただきたいと思います。
- あと、お気づきかもしれませんが、「年のみ抽出」「月のみ抽出」という機能は、実は過去に、いったん私も実装したことがあります({{雑多な内容の箇条書き}}のノート等をご参照ください)。しかし、必要とされる特定の場合にのみ必要な機能だったので、それを必要としない場合に対しての負荷を無用に増やさないよう、方法を考え直して元に戻し、その代わりに、それを必要とする各々のテンプレート内のその箇所においての個別処置にしてあります。--しまあじ(会話) 2013年10月7日 (月) 06:22 (UTC)
- コメント #timeで扱えない「Y年n月」を処理できるのが大きなアドバンテージであるわけで、その提案内容だと意味があるのか疑問です。
- 私のニーズとしては、年数と月数の値の算出は別に対応することにしましたので、そこまで固執されるならエラーチェックの精度や出力書式の機能拡張は無くても良いです。技術的な事柄以外の問題でとりとめがつかなそうなので。しかし、#invoke:TimestampFormatterのほうは、処理の負荷がさほどでないなら非常に便利そうなので、優先的に導入して頂ければと思います。。——以上のコメントは、ディー・エム(会話が 2013年10月8日 (火) 14:37 (UTC) に投稿したものです(本人による付記)。
新改定案(C案)
[編集]- 提案 とりあえず「Template‐ノート:複数の問題#旧仕様形式で記入されている日付を現仕様形式へ置換するBot作業依頼提案」で出ているHmanさんの要望への対応を優先し、checkdate/sandboxを書き直しました[4](私の希望も同じくです)。#time関数の使用に対して異論が出ていましたので、汎用性をオミットして対応しました。--ディー・エム(会話) 2013年10月8日 (火) 14:37 (UTC)
- あちらのノートの他のお二人のかたからのご意見中の表現にある「バグ的」という表現、つまり、たとえ私が「バグ的」に意図せずに追加してしまった機能、単純にいってしまうと、まさに「バグ」なのです。その私が発生させてしまった「バグ」を、「非常に便利」と活用してくださっていたかたがいるらしいわけなのですが、私としては、そういう用途として追加した機能ではなく、あくまで「バグ」なので、その機能については「不対応」にしたいんですけど、私の発生させた「バグ」が、そんなに便利なのでありましたら、その「バグ」の継承も、やむを得ないかなあ、とも思ってはいるところなのですが。--しまあじ(会話) 2013年10月8日 (火) 14:52 (UTC)
報告 少し早い目ですが、早期修正の要望もありましたので、上記のとおり改訂しました。--ディー・エム(会話) 2013年10月11日 (金) 15:14 (UTC)
条件式についての追記
[編集]2013年10月11日 (金) 16:36 (UTC) の版[5]の仕様について、計算式自体を極力簡単にするために判定式の内容が若干複雑になってる部分があるので、自分用の備忘録も兼ねて条件判定の動作原理を以下に追記しておきます。
- "yyyy-m(m)"形式の入力に対する判定式
- 年の数値yyyyが4桁の正の整数(仕様上、入力値の有効範囲は4桁の自然数=1000〜9999年です)かつ月の値m(m)が2桁以下の自然数かどうかをチェックしています。
- 入力値(引数1)の先頭6文字を、X
- マイナス記号より左の文字列を、Xa
- マイナス記号より右の文字列を、Xb
- 当該判定式の1番目の#expr文(trunc{{padleft:|4|{{{1|}}} }})を、条件式A
- 当該判定式の2番目の#expr文(trunc-(-0.{{padleft:|6|{{{1|}}} }}))を、条件式B
- と表すと、当該の条件判定式のロジックは次のようになります。
- 条件式より、Xは1つのマイナス演算子と2つの数値からなる。(#exprの出力値は単一の数値のため、数字・負号・小数点の組み合わせのみで演算子は含まれない)
- 条件式A,Bより、Xの4,6文字目は演算子(or 正負符号)でない。(条件式A,Bが計算エラーとならないための必要条件)
- 条件式A,Bと条件1より、Xは小数点を含まない。(trunc(Xa)=Xa、trunc-(-Xb)=Xb)
- 条件3より、Xbが2文字以上のとき1文字目の数字は0でない。(ただし、後述の条件によりXbは2文字以上でなく1文字の数字)
- 条件式Aと条件4より、Xの2,3文字目はマイナス演算子でない。(条件式A(Xの先頭4文字)=a-b(a=Xa, bはXbの先頭1or2文字の数字)と仮定すると、b=0でないときa=a-bを満たすa,bは存在しない)
- 条件2,3,5より、Xの5文字目がマイナス演算子で、Xaは4文字の整数(4桁の正の整数もしくは3桁の負の整数)、Xbは1桁の正の整数。(Xの1~4文字目=Xa、Xの6文字目=Xb)
- 条件式Bと条件6より、Xの1文字目はマイナス記号(負号)でない。(Xa=-a(a=0でない)とするとき、Xb=trunc-(0-a-Xb)を満たす-aは存在しないため)
- 条件6,7より、Xの5文字目はマイナス記号、それ以外の文字は全て数字。
- 以上の原理で、X(入力文字列の先頭6文字)が "4桁自然数-1桁自然数"(Xの右側に数字1字が隣接する場合は必然的にマイナス記号の右側が2桁の自然数)の形と一致するかどうかを一度にチェックしています。
- 条件式A,Bで使用している演算子truncのうち条件式Aのtruncは年数に小数点が混じっていないかをついでに確認しているだけなので別に無くても大きな問題はないですが、条件式Bのほうのtruncは上記の条件5に必須で、Xaの数値を少数に変えて除去すると同時に、"xx-0.x" と "x-0.xx" の形の入力をこのtruncの条件式ではじいています。ちなみに "yy-mm-dd" などの入力は#time関数の方の分岐にまわされますが、使用することは可能です(判定式の仕様上、#time関数行きのやつは時刻を併記して入力するとエラーになります)。
- "yyyy年m月" と "yyyy-m(m)" 形式以外の入力に対する判定式
- 入力文字列の中に年と月、両方の値が含まれているかどうかチェックした後、#time関数により年と月の値を抽出しています。#timeの書式判定の規則と合致しない形式で入力された場合にユーザーの意図しない出力となるケースを予防するためと、年と月のいずれかしか入力されていない場合に編集時点の年or月(or日)がその都度代入されてしまうのを防止するための処置です。
- 入力値に4文字の数字列が含まれるとき、#time関数では
- 4文字の数字列が年数(yyyy)または時刻(hh:mm)と解釈される。
- 年と時刻のどちらとも解釈可能な4桁数が2つある場合は、月(日)と一連で入力された値が優先的("xxxx Month xxxx" の場合は左隣優先)に年の値として扱われる。
- 時刻とみなせない4桁数(上2桁が25以上or下2桁が60以上)は優先的に年の値として扱われる。
- 年の値とみなされる文字列が複数あるときは、より右側にある値が優先的に採用される。
- #timeが取り扱い可能な年数の範囲は0000~9999まで。値がこの範囲外となった場合はエラー。
- という出力をします。Template:checkdateの判定式ではこの性質を用い、引数1(日付値の入力文字列)の右側に4文字の数字列 "2100"(2060以上でなおかつ時刻とみなされる4桁数であれば良い)と "+7940year"(日付に7940年加算)を挿入して#timeを実行することで当該目的の判定を行っています。入力値が2060年以上(7940を加算して9999を超える数)の年数のとき、もしくは年とみなせる4桁数が月と一連で入力されていない場合に、エラーと判定されます。2060年以上の入力値をエラーとして除外しているのは、条件式を1つだけに簡略化するため(優先的に年の値として扱われる年数の入力に対して、この条件式だけでは真偽の判定ができないため)です。
という感じです。--ディー・エム(会話) 2013年10月13日 (日) 10:58 (UTC)