めあとるーむ記録帳

なんか書く

JSONのkeyにあたるstringの覚え書き

JSON は最近のネットワークを通じたデータのやり取りでよく使われている。Web サービス以外にもゲームや設定ファイルに使われることがあるぐらい。

そんなわけでライブラリもそろってるし、お仕事でも機能の切り分けとして WebAPI 化したりする際に使った。

ただ、どうしても環境が環境でちょっとライブラリが使えず、まあそこまで複雑な仕組みにならないということで手書きで JSON を出力するコードをある時に書いた。 そのコードを用いて吐き出した JSON を、別環境で読み込ませようとしたときにエラーが起こった。

なんと別環境で使っているライブラリで読み込めないというケースが発生したのだ。

そのとき使っていたライブラリは Google GSON というライブラリ。

github.com

これは JSONJava オブジェクトにシリアライズしたりデシリアライズしてくれるライブラリ。

不思議なことに一部はできていたが、途中からできていなかった。JSON の形がおかしいのかと疑ったが、整形はできるし JSON.org を見てもおかしな点はない。

はてさてなぜやらと思いつつ調べると、デシリアライズに失敗した部分の key が大文字から始まるという共通点があった。

{ "Hoge" : "fuga" }

みたいな感じだったのだ。これを

{ "hoge" : "fuga" }

とすると問題なく通った。


ふと調べてみると TwitterAPI とかは key の文字列が小文字から始まっていた。困ったときは仕様書に帰れというわけで、そんな決まりでもあるのだろうかと思い RFCECMA を調べてみた。

JSON が関係する仕様書は

と思われる。上から順に

2つ目と4つ目は同じことを言ってる通り、中身もたぶん同じ。策定文書が違うだけだと思われるが一応上げておく。EcmaJavaScript などの親分的存在。まあそれはさておき。

とりあえず JSON の key に関する情報を集める。

http://www.json.org/object.gif

まんま json.org から引用したが、このとおり。つまり string(文字列?)であれば何でもいいように書いてある。

では string の定義を見てみる。RFC4627 には以下の通り。

A string is a sequence of zero or more Unicode characters [UNICODE].

string は0文字、あるいはそれ以上の Unicode の文字の集まり。

これは Introduction での記述。別途あった Strings では以下の通り。部分抜粋。

A string begins and ends with quotation marks. All Unicode characters may be placed within the quotation marks except for the characters that must be escaped:quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).

stringsの始まりと終わりはクォーテーションです。すべてのユニコードの文字が使え、エスケープを用いることでクォーテーションマークなど(具体的にはバックスラッシュや水平タブなど)の文字も使えます。

JSON.org にもっとわかりやすい図があった。つまりこういうこと

http://www.json.org/string.gif

引用しなかったが、特殊な文字の表現についてなどが書かれている。

Parsers の項を見てみたが、この辺りは JSON の形式にちゃんと対応すること、実装時によってはネストの深さや文字数によっては対応できないものがあるかもしれない、程度の注意書きだけだった。

この辺りには大文字の使用の制限に関しては存在しない。気になるところというと、同項(String)の以下のくだり

The representation of strings is similar to conventions used in the C family of programming languages

strings の表現はC言語系の形式にほぼ同じ

とはいえこれがkeyに該当する変数名のコーディング規約のたぐいだと取るのは拡大解釈が過ぎる気もする。

そしてRFC7159を見て驚愕した。13項Exampleでこんなものが書いてあった

This is a JSON object:

{
 "Image": {
      "Width":  800,
      "Height": 600,
      "Title":  "View from 15th Floor",
      "Thumbnail": {
          "Url":    "http://www.example.com/image/481989943",
          "Height": 125,
          "Width":  100
      },
      "Animated" : false,
      "IDs": [116, 943, 234, 38793]
    }
}

めっちゃ大文字使ってるやん

つまり、単にGoogleGsonが対応できてないというだけの話だった

今さら始めるFGO

FGOの第1部が終わって1ヶ月ほど経過した。

年末にガーッと盛り上がったこともありユーザーが増えているようだが、ぶっちゃけ先にいうと

FGOはめっちゃ不親切なゲームである。

先ほど言ったとおり、そろそろはじめて1ヶ月ほど経過するわけで、やはりドロップアウトする人が増えつつあるようだと思う。

初心者向けの紹介ツイートなどもあるが、ぶっちゃけそれより先に覚えることがあるのでそれを教えておこうかな、と思ってこの記事を書く。

0. 型月が合わないならやめておけ

まず言っておくが、このゲームは型月ゲーである

何を今更だが、このゲームはType-moonのブランドを冠している。過去、型月作品を触れて合わなかった人間はまず合わないと思ったほうがいい。

なぜなら、このゲームのよさのかなりの部分を型月の空気が占めているので、はっきり言ってそこが合わなければもはやこのゲームはただの不親切なゲームになってしまう。

では過去の型月作品を触れるかというとそこまでは言わない。もしはじめてなら、とりあえず序章、1章あたりをプレイしてシナリオを読んで欲しい(スキップはすべきではない)。

もしそこで「続きが気になる」とか「嫌いじゃないなこういうの」とか「キャラクターに感情移入してしまった」という部分があれば問題ないと思う。

おすすめは3章以降なのだが、まあそこまで行くのは長いのと、初期に実装された部分がめっちゃ不親切な部分が強いのでそこを越えるのはちょっとつらいと思う

1. クラス相性を考えろ

ではプレイするときに覚えることだがまず一つ目。覚えなくても意識するぐらいでもいい

FGOでは戦闘時、クラスによって有利不利がある。スキルなどでは攻撃力20~50%アップ程度(各種差はあり)のバフになるが、クラス相性は純粋にダメージが倍になったり半分になったりする。

レア度より先にクラス相性を考えるのが一番である。フレンドを選ぶ画面でも表示されるが、ぶっちゃけUIが分かりにくいというまたこの不親切さが(ry

以下まとめる

  • セイバーはランサーに強い
  • ランサーはアーチャーに強い
  • アーチャーはセイバーに強い
  • ライダーはキャスターに強い
  • キャスターはアサシンに強い
  • アサシンはライダーに強い
  • ルーラーはセイバー、ランサー、アーチャー、ライダー、キャスター、アサシンから受けるダメージを半分にする。アヴェンジャーに弱い
  • アヴェンジャーはルーラーに強い
  • バーサーカーは上の全てのクラスへ与ダメも被ダメも倍になる(上の全てに強く、全てに弱い)
  • シールダーは全てに等倍
  • 一部ボスなどは別枠

ほらめんどくさいでしょう

でもぶっちゃけこれを覚えるところから始まりだし、これがわかってないと多分ずっと苦労する。バサカで殴るのは楽だけど受けるダメージも増えるので扱いが難しい。アヴェンジャーあたりは楽ではあるが、うまくクリティカルスターを調整しないとHP70万ぐらいのボスを削りきれなかったりする。

なので、強いキャラとかはあんまり関係ない

もちろん星5はだいたい強いが、○○さえ入れておけば何も考えなくていいということは絶対にない。

そもそも戦闘で3人パーティに並べるわけで、1体で全部済ませるようなキャラはいない。クラスさえ相性が良ければ全員星1とかでもどうにかなったりする(シナリオ後半からはつらいが)

ついでにいうと、マスターレベルが低いうちはコストの都合入り切らないので、低レアも使うことになる。その場合、やはりクラス相性を一番に考えたほうがいい。

2. 育成はレベルから

基本このゲームはレベルを上げて物理で殴るのが一番早い。シナリオ後半からスキルとかを考える必要が出てくるが、まず前提条件としてレベルマックスである。

面倒なようだが、ある程度戦力が揃ってくると曜日クエストの種火集めが安定するようになり、ぶっちゃけ作業になる。

まあこれがこれで面倒だったりするのだが、忘れてはいけない、このゲームは結構不親切である。

ちなみにレベルを上げようとすると再臨でつまずくことになると思うが、とりあえず詰まったら他のキャラのレベルでもあげておけばいいと思う。

レベルはメニューの強化から手動でやる必要があるのでそれも忘れないように。多分、序盤ならドロップやフレポガチャの小さい種火をマメに食わせたりしておけば20ぐらいまでは行けるはず。

まあ金の種火の100分の1ぐらいの経験値しか入らないが。

3. アイテムの集め方

基本的にドロップはめっちゃ渋い。加えて一部素材はシナリオ後半にしか出てこない。

つまり、シナリオ序盤のタイミングで後半に出てくるキャラを引くと第1再臨で詰まってしまうケースもある。

そんな時に頼りになるのがイベントである。イベントは素材回収のタイミングである。

問題はFGOのイベントは割とスパンが長いことだ。大体3カ月に2回ぐらい。イベントがないタイミングも結構ある。

新年になってから復刻イベばっかでしかも1つは監獄塔とか高難易度イベをやるあたり本当に運営は不親切である。

ちなみに初期は未実装シナリオで出てくるアイテムが再臨素材に要求されていたりした。その時もイベント頼みだった


まずこの4つ。本当にそのぐらい。

戦闘であれこれ気にすることなどもあると言えばあるのだが、初心者にはいらないと思うのであえて言わなかった。多分Wikiとかに書いてると思うので自分で読むといい。

もう一度言うが、FGOは基本不親切なゲームである。それを把握したうえで楽しんでもらいたい。

Powershellに入力リダイレクトは存在しない(今のところ

ファイルから入力するケースというのは結構ある。mysqldumpで輩出したファイルを読ませたりとか。

# echo < file

こんな感じで入力する。ところがPowershellでは

> echo < file
発生場所 行:1 文字:6
+ echo < file
+      ~
演算子 '<' は、今後の使用のために予約されています。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : RedirectionNotSupported

こうなる。じゃあエスケープか何かがあるかというとない。

出力では Out-File というコマンドがあるが、じゃあ入力では?と思ったらない。

もしかしたら何か方法があるかもしれないが調べてみても出てこない。仕方がないのでcmdって打ってコマンドプロンプトでやろう(コマンドプロンプトではリダイレクト入力できる)

第n何曜日を計算する

いくつかの祝日とかゴミ捨てとかはmmddであらわされず、基本的に特定の月(あるいはすべての月)の特定の回数目の曜日に行うと決まっている。

祝日はまあその手のAPIサービスを使うとして、ゴミ捨てなどをデータベースに入れるにはどうしたものかと思いつつ、とりあえず毎月特定の日に起こるイベントをまとめたテーブルを作ることにした。

毎週起こるイベント(燃えるゴミの日とか)はエブリウィークのテーブルにしつつ、毎月第一水曜日の燃えないゴミの日などを管理するという感じ。

カレンダーとかリマインダーのデータベース設計したことないんだけど何かいい資料があるなら教えて。

とりあえず第n何曜日の定義はその月の何回目何曜日かということで、抽象的すぎるから具体的にみんな大好き月曜日で考える。

第1月曜日その月の1日~7日の中にある。1日が火曜日なら7日が月曜日、1日が日曜日なら2日が月曜日。

同様に第2月曜日は8日~14日の中にある。あるいは第1月曜日の日付を把握できたのであればその日付に7を足せばいい。後は同様に考えればいい。

以上からまず計算に必要な要素は

  • その月のどこかの日付と曜日(基本は第1日が計算しやすいと思われる)

さえあればとりあえず計算できる。

MySQLなら特定の日付の曜日を取得する関数はDAYOFWEEK(日曜日はじめ)とかWEEKDAY(月曜日はじめ)があるのでそれを使えばとれる。

mysql> SELECT WEEKDAY(yyyymm01);

これの答えがyyyy年mm月1日の曜日である。WEEKDAYの月曜日は0で返ってくるので、7進数で考えて、7からこれの答えを引くと月曜日までの日数が分かる。

もうちょっと具体的に2017年1月で考えて、

mysql> SELECT WEEKDAY(20170101);
+-------------------+
| WEEKDAY(20170101) |
+-------------------+
|                 6 |
+-------------------+
1 row in set (0.03 sec)

1月1日は6=日曜日だ。では2017年1月の第1月曜日は

mysql> SELECT 7-WEEKDAY(20170101);
+---------------------+
| 7-WEEKDAY(20170101) |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)

つまり1日後、1月2日ということになる。

mysql> SELECT 20170101+(7-WEEKDAY(20170101));
+--------------------------------+
| 20170101+(7-WEEKDAY(20170101)) |
+--------------------------------+
|                       20170102 |
+--------------------------------+
1 row in set (0.05 sec)

まあこうでもいい。週ごとに以下数字から引けて、1日の日付に足せばいい。

func sun mon tue wed thu fri sat
WEEKDAY() 6 7 8 9 10 11 12

あるいは足し算で出てきた結果と足す形にした方がいいかもしれない。そこは適宜数字を変えるとして。

そして第2曜日以降は各々の数字に7を足す。第2月曜日なら7+7という感じ。

この辺りは関数化して求められるようにするのが理想だろう。たぶん。

すでにあったら申し訳ねえが教えてくだされ


追記

なんかDAYOFWEEKだとうまくいかなかったから削除。理屈は同じだけど考えるのが面倒なのでやりたい人は勝手にどうぞ

FGOの1部が完結した

Fate/Grand Orderというゲームがある。開発はディライトワークスとタイプムーン

www.fate-go.jp

これが昨日(2016/12/25)に完結した。

完結したという表現はやや語弊があるが、諸々思ったことがたくさんあったので記しておきたくなった。

一応酒を飲み酔ったニワカ月厨が喚いてるだけなのでそれは気に留めていただきたく。

以下、FGO本編及び2015年7月から2016年12月までに行われたイベントのネタバレを含むかもしれないし、含まないかもしれない


もともとこのゲームは初期勢だった。 初期勢なので、伝説の48時間メンテや1章のワイバーン地獄、 さらには低レア配布イベントというイベントとも言えないイベントからやっている。

当時は型月(Fate)にややはまりつつのニワカだったのだが、やる夫スレ系掲示板で型月厨が多い環境にいたこともあり 興味を増しつつあった。

それはそれは、当時はあまりいいゲームとは言えないものだった。 取ってつけたようなシナリオ、慣れていないことが分かる運営の対応、 相次ぐ緊急メンテナンス。 おそらく有象無象のソーシャルゲームでもよくあるダメなゲームの形だったと思う。

恥ずかしながらゲーマーを名乗りつつ、遊んだことのあるソーシャルゲームは現状 後にも先にもFGOのみなので、比較対象はない。ただ、当時はその調整不足の難易度が 逆にゲーマー的に限られたリソースでどこまで行けるかという執念を焚き付けたのは覚えている。

途中イベントに参加しなくなったり、少しログインしなくなったりというモチベーションの上下はあったが、 そうしているうちに1年と5ヶ月ほどが経ったのだ。


型月の一番の魅力はどう考えてもきのこの文章だと思う。

良くも悪くも中二病を刺激する文章と設定、それらが綿密に組み合わさった上で王道を収めるシナリオは 最高の作品になっている。社長が惚れたのも納得である。

FGOは始まったばかりのときはソーシャルゲームの鉄則を守っていた。

それは要はログイン率を上げ、プレイ時間を増やさせる一種のノウハウだろうと思う。

例えば、3分に1回のペースで戦闘(プレイヤーの介入)を行わせる。 1つのイベント・シナリオでは一定量以下の文章に収める。などなど。

そのような決まりごとは徐々に剥がれていった。

当初シナリオは東出祐一郎さんと桜井光さん(それぞれFateシリーズの外伝を執筆)が担当し、 シナリオ監修に徹していたきのこは徐々に仕事量を増やしていった。

イベントのシナリオを書いてと言われ1日で書き上げたり、設定を作ったからイベント追加しようって言ってみたり。

文章量も徐々に増え、サービス開始1年後の2016年7月には本編6章で500kbを書き上げた (しかもマスターアップ数ヶ月前に一度全て破棄、書き直しという展開)。

イベントやシナリオでは地の文が増え、独白が増え、さらにもともとエロゲ・ノベルゲーであったノウハウを活かし イラスト・演出を豪華にしていく。おそらく振り回されたデイライトワークスは大変だっただろう。

BGMは増え、演出は豪華になり、キャラクターの魅力は極限まで磨かれていく。 ときにはひたすらキャラクターが会話するだけで戦闘すらないシーンすら追加された。 だがそういった会話の数々で、当初使い捨てにようにでていたキャラクターは イベントで掘り下げられ、設定が追加され、 加えて新たなキャラクターは全てに魅力を付与された。 終盤の本編では新旧合わせて20人近いキャラクターが動き、考え、戦い、守り、そしてほぼ例外なく散った。 とてもまともなシナリオライターでは持て余すキャラクターたちを動かしきったのだ。 動かしきって、活かして生かした上で、散らせたのだ。

某所ではシナリオマーケティングという言葉が生まれた。

シナリオ中で活躍し、それ故ガチャを回して欲しくなるというものだ。

それは高レアもさることながら、低レアとて例外ではなかった。


Fateシリーズの外伝の1つにApocryphaというのがある。

これは1つのイフの世界の話で小説版と漫画版が展開されているが、実はこれはもともと 携帯電話向けのゲームとして開発したかったものだという。 それが没となり、材料だけ用いて再度作り直した小説がApocryphaだそうだ。

おそらく、それでやりたかったことの1つが叶えられたのだろう。

最終決戦はレイドボスイベントだった。おそらく終わったらシングルモードとして実装されるが、 みんなで最後のボスと戦うという演出をしたかったのだろう。没になったApocryphaでやりたかったことだと思う。

そのお祭り感といったら、レアドロップの魔神柱が刈りつくされるという最終イベントならぬ 採集イベントなどと言われた。だが、そのお祭りから一転、終わった直後は感動の感想が流れた。

皆が盛り上がり、皆が動き、皆が感動して終わる。

終わり方としてはこれ以上のものはないだろう。おそらく最高の終わり方だ。

オンラインゲームやコンシューマーゲームでは多分ここまでの演出はできない。

1年半という短くない時間を様々な形でともにしたゲームと ソーシャルゲームという形ではおそらく最善で最高の形だと思う。

終わったあとに、余韻で残ったスタミナを消費することすらためらわせたのだから驚くべきことだろう。


物語を完結させるというのは難しい。

小説や漫画やあるいは何でもいいが、何か物語を作ろうとした場合まず難しいのは出だしだと思う。

始まりを作る。一文目、一コマ目、それらは悩んで始めることになる。

だが、それは始まってしまえばそう難しいものではない。 設定が増え、キャラクターが増え、やりたいことが増えていく。 そういうものだ。経験があればよくわかると思う。

しかし、終わらせることは難しい。

プロの作家でさえ、プロの漫画家でさえ、なんであれ、美しい終わりを作ることは至難の業だ。

一体どれだけの作品が終わることができずにいるか、終わらせてもらえずにいるか。

深夜アニメのように最終回までの話数が決まっているならいいが、 ソーシャルゲームのように人気がなくなる=終了、つまり人気がある限り終わることができないわけで、きれいに終りを迎えるのはほぼ不可能だろう。

事実、ソーシャルゲームは基本的に「イベントが本体」であり、継続的な運営によって成り立つものだ。

ましてやソーシャルゲームにスタッフロールの流れるエンディングなど普通はない(と思っている)。

だが、イベントを脇役にして、本編を主軸として、FGOは終わらせた。2部があるとは言われているが、まず終わらせた。

それも、人々を衝き動かすほどの終わり方をした。感動させる終わり方だった。

始めるのは難しいが、無理ではない。だが、終わらせるのは至難の業だと思っている。

やっていたら、どこまでもやりたくなるのが作る者の心理だ。 風呂敷は広げ続けたくなるものだ。

でも、終わらせたのだ。

蛇足もなく、やや(伏線回収の)不足こそあれど、型月では割とよくあることなので そのうち回収されるだろう。

終わらせた。それだけで賞賛に値すると思っている。


1つだけ気になることがある。

ディライトワークスの社長に庄司顕仁という人物がいる。

実は彼の名前は、ある時までFGOのスタッフクレジットに載っていた(と思う。確認ができてない)。

今はこの名前が消えている。どこにもないのだ。

そしてFGOは割とリアルのイベントを多くこなしている。ニコ生やマチアソビなど、様々な場所に出て、 スタッフも顔を出している。

だが、この人物だけはどこにも出てこないのだ。

初期の初期、型月の恥晒しとしてFGOが扱われていた頃、彼に対するヘイトは凄まじかった。

この仕事も社長(武内崇)の知り合いで取ってきたとか言う話だった。

正直に言うと完全な擁護こそできないが、しかしここまでの型月の無茶振り対応、最悪 きのこの「じゃあもうFGO畳む」という発言で本当に畳んでしまいそうな運営方針をしている あたり、小さなディライトワークスをうまく支えている人物だと思っている。

もちろん内情は全くわからないのでなんとも言いようがないが、 この人物が本当に実在しているのか、それが気になるのだ。

ともかく、彼も含め、ディライトワークスのスタッフとタイプムーンのスタッフ、 そしてFate/Grand Orderに関わったすべての関係者に感謝と敬意を示したいと思う。

ありがとうございました。私の中では、1つのソーシャルゲームの極地に至った冠位「グランド」のソーシャルゲームでした。

iPhoneを買った

買った。なお数週間前

これが最後のApple製品になると思ってた。

iPhone7じゃなくて6Sなのでやや古い。まあ気が向けば来年また買い換えるでしょう多分。


購入したのはスーパーマリオランが遊びたかったため。ただそれだけ。

ゲームのためにハードごと買うのはもはやゲーマーの意地でもあり常識でもあるので個人的には特に衝撃ではないのだが、まあ世間的にはそうでもないらしい。

supermariorun.com

今さらだけどスーパーマリオランってドメイン取ってたのね。

ちなみにAndroid版は来年出す予定らしい。つまり待ちきれなかったのだ


買ってわかったことがあるが、やはりiPhoneはハードウェアの設計がすごいっぽい。

なんというか、持っていて愛着が湧きやすいというか、手に握っていたくなるというか、そういう魅力がある。

さわり心地や握り心地がいいのだ。たぶんそう設計されてる。

できればカメラの出っ張りをどうにかしてほしかったが。


あと思ったこととしてOSの設計思想もだいぶ違う。AndroidWindows 10 mobile(Windows Phone)は戻るボタンで戻ってアプリを終了するという考え方が強いがiPhoneはホームボタンしかないのでそれを押すことで中断する。ユーザーに終了の権限がほとんどない(タスクマネージャーで手動終了できるがあれで終了したからと行ってバッテリーの持ちは変わらないらしい)。

ただやっぱりコントロールのためのUIが画面上にあるのはつらい。画面が大きくなってきたこともあってかつらい。左の画面端からスワイプしたら戻れることが多いけどね。

持って初めて分かったが、ハードウェアとしての完成度は高い。ソフトウェアとしては、ちょっと古い部分が厄介になってきてる。

そんな印象

MySQLで日付を計算する

SQLで今の時間をとるにはcurrent_timestampを使っていた。べつに問題ないし、どんなふうに出てくるかというと

> SELECT current_timestamp

って打ったらわかる通り。

これを使って動的に今から10分以内であれば~~という比較をすると

> ~ WHERE time_column>current_timestamp '-10 min'

とやっていた。PostgreSQL 8.1.6(すごくふるい)ではこれで通っていた。

が、MySQL 5.7.6で同じ条件を付けると通らなかった。厳密にいうと通るのだが、常にfalse判定されてるらしくtrueで出てきそうな行も出てこなかった。

mysql> select current_timestamp > current_timestamp '-10 min' ;
+---------+
| -10 min |
+---------+
|       0 |
+---------+
1 row in set (0.05 sec)

見た感じだと'-10 min'の記述が悪いらしい。

mysql> select current_timestamp > current_timestamp - 10;
+--------------------------------------------+
| current_timestamp > current_timestamp - 10 |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
1 row in set (0.00 sec)

なるほど確かにだ。じゃあ10分というのを変換するにはどうするかと考えたが(上のでは-10秒)

mysql> select current_timestamp > current_timestamp - '0000-00-00 00:10:00';
+---------------------------------------------------------------+
| current_timestamp > current_timestamp - '0000-00-00 00:10:00' |
+---------------------------------------------------------------+
|                                                             0 |
+---------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

あれ。だめだった。 素直に10分を600秒にしてもいいのだがせっかくだしいろいろやってみる。

mysql> select current_timestamp - '0000-00-00 00:10:00' ,current_timestamp;
+-------------------------------------------+---------------------+
| current_timestamp - '0000-00-00 00:10:00' | current_timestamp   |
+-------------------------------------------+---------------------+
|                            20161214152055 | 2016-12-14 15:20:55 |
+-------------------------------------------+---------------------+
1 row in set, 1 warning (0.00 sec)

時間が変わってないところを見るとそもそも引き算の対象としてはとれないらしい。Warningにもそう書いてある( Truncated incorrect DOUBLE value: '0000-00-00 00:10:00' とのこと)

mysql> select current_timestamp - 00:10:00 ,current_timestamp;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':10:00 ,current_timestamp' at line 1
mysql> select current_timestamp - 00-00-00 00:10:00 ,current_timestamp;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '00:10:00 ,current_timestamp' at line 1

うーん、素直に600秒で引き算するのが一番楽そうだ

mysql> select current_timestamp - 600 ,current_timestamp, current_timestamp>current_timestamp-600;
+-------------------------+---------------------+-----------------------------------------+
| current_timestamp - 600 | current_timestamp   | current_timestamp>current_timestamp-600 |
+-------------------------+---------------------+-----------------------------------------+
|          20161214153421 | 2016-12-14 15:40:21 |                                       1 |
+-------------------------+---------------------+-----------------------------------------+
1 row in set (0.01 sec)

あれ?6分で引かれてる?

mysql> select current_timestamp - 10000 ,current_timestamp;
+---------------------------+---------------------+
| current_timestamp - 10000 | current_timestamp   |
+---------------------------+---------------------+
|            20161214144353 | 2016-12-14 15:43:53 |
+---------------------------+---------------------+
1 row in set (0.00 sec)

つまり、下から2桁を秒、下から3,4桁を分、という風に扱ってるらしい。

まさかこんな仕様だとは思ってなかった