NCMBのquery仕様、createDate/updateDate周り【C#】【Unity】

月間ランキング機能をNCMBを使って実装できないか色々試した結果、判明した仕様や注意点についてメモ書きします。よく調べれば公式ドキュメントに載ってる内容と被ってるかもしれません。

##概要
データストアのcreateDate/updateDateフィールドが曲者だった。

これらはデフォルトで設定されるフィールドですが、管理画面で型を調べようとしてもよく分からないし（多分DateTime型でいいんだろうけど）、手動で変更できないし、扱いが特殊になってます。

で、実際にクライアント型で操作する際にも癖があったのでそれらをメモ書きします。


##queryの条件にはcreateDate/updateDateを指定できる
結果をソートする```query.OrderByDescending()```では、createDate/updateDateを引数に設定してちゃんと動きました。うんうん。

月間ランキングには期間で抽出する必要があったので、恐る恐る```query.WhereGreaterThanOrEqualTo()```にDateTime型で渡してあげると、これも動作してくれるようです。よかったよかった。


##クライアント側でcreateDate/updateDateの値は取れない
通常、queryで取得したNCMBObjectは、```NCMBObject["フィールド名"]```でアクセスできます。自前で実装したフィールドでこれで大丈夫です。しかし、同じノリで```NCMBObject["createDate"]```や```NCMBObject["updateDate"]```と書いて取得しようとすると「そんなkeyはない！」と怒られてエラーで落ちました。

```NCMBObject.Keys``` で含まれるKeyの一覧を取れるので見てみると、確かに無い。
無いのかよ・・・

※追記
コメントで教えて頂きましたが、どうやらプロパティで取得できるようです。

```C#:
        void OnResult(List<NCMBObject> objList)
        {
            Debug.Log(objList[i].CreateDate);
            Debug.Log(objList[i].UpdateDate);
        }
```

##サーバー側のcreateDate/updateDateは標準時刻で保存されている
厳密な仕様を確かめようと分単位で```query.WhereGreaterThanOrEqualTo()```を実行して調べてわかったのですが、サーバー側では標準時刻で保存されてました。

↓↓管理画面上は日本時刻で表示されている（ように見える）ので注意ですね。
<img width="501" alt="ScreenShot 2018-12-13 0.48.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/237014/b4e6e550-a0ba-6940-6eb2-0f5c1582403a.png">




##テスト用コード
```C#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NCMB; //追記
using System;

 public class NCMBTest : MonoBehaviour
    {
        [ContextMenu("Test")]
        void Test()
        {
            StartCoroutine(TestCoruotine());
        }

        private IEnumerator TestCoruotine()
        {
            bool isConnecting = true;

            if (NCMBUser.CurrentUser == null)
            {
                // ログインしていない
                yield break;
            }
            NCMBQuery<NCMBObject> query = new NCMBQuery<NCMBObject>("クラス名");
            //一致する値で取得（例えばユーザーID）
            query.WhereEqualTo("キー", "値");
            //ソートkeyを設定,updateDateやcreateDateもOK
            query.OrderByDescending("updateDate");
            //12/1~12/31で抽出,DateTime型で渡せばOK
            query.WhereGreaterThanOrEqualTo("updateDate", new DateTime(2018,12,1));
            query.WhereLessThanOrEqualTo("updateDate", new DateTime(2018, 12, 31));
            //検索結果を取得
            query.FindAsync((List<NCMBObject> objList, NCMBException e) =>
            {
                if (e != null)
                {
                    //検索失敗時の処理
                    Debug.Log("失敗");
                }
                else
                {
                    Debug.Log("成功");
                    //objListを使う処理
                    OnResult(objList);
                }
                // ログイン処理終了
                isConnecting = false;
            });

            // ログイン処理が終了するまで以下の行で待機
            yield return new WaitWhile(() => { return isConnecting; });
        }

        void OnResult(List<NCMBObject> objList)
        {
            /*君だけの処理を書こう！*/

            //ただし...
            //エラーになる
            Debug.log(objList[0]["createDate"]);
            //エラーになる
            Debug.log(objList[0]["updateDate"]);
        }
    }
```