※2019/06/30 コード修正
やりたいこと
端末から日時を取得する場合、端末の時刻を操作されると狂ってしまう。ということで、端末以外から日時を取得したい。
その方法を叶えてくれるのが NICT(日本標準時(JST)グループ)様
なんでも、json形式で日時を配信してくれているらしいです。個人利用も無償でOKらしいですが、制限があるそうです。
Q&Aより
1時間平均で20回(1日の合計が480回)を超えないようにしてください。 それ以上が必要な場合は事前にご連絡ください。
参考サイト様
blog.anzfactory.xyz
概ね、杏z学習帳様の方法を真似させていただいてるのですが、自分用にカスタマイズしたものをメモ。
コード
(1)NTP(https://ntp-a1.nict.go.jp/cgi-bin/json)から時刻を取得 Request()
(2)PCとの時刻を比較して不正がないかをチェック CheckPCTime()
修正:差を求めて誤差5秒未満ならOKとした。
(3)(1)(2)をStart時に行う
(4)実行メソッドはGetDateTime();
不正がなければ、PCから現在日時を取得し、不正があればNTPから取得する。
(5)Start時のチェックを何度も行わないようにシングルトンにする。
(NTPへのアクセス数を減らすため)
新規でゲームオブジェクトを作成してこのクラスをアタッチしておくこと。
using System; using System.Collections; using UnityEngine; using UnityEngine.Networking; public class TimeStamp : MonoBehaviour { static readonly string NTP_URL = "https://ntp-a1.nict.go.jp/cgi-bin/json"; static public TimeStamp instance; private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(this.gameObject); } else { Destroy(this.gameObject); } } void Start() { StartCoroutine(CheckPCTime()); } IEnumerator Request(Action<DateTime> callback) { var request = UnityWebRequest.Get(NTP_URL); yield return request.SendWebRequest(); if (!request.isNetworkError) { var json = JsonUtility.FromJson<NTPDate>(request.downloadHandler.text); var startDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); var unixDate = startDate.AddSeconds(json.st); callback(unixDate.ToLocalTime()); Debug.Log(unixDate.ToLocalTime()); } } public class NTPDate { public string id; public double it; public double st; public int leap; public long next; public int step; } bool isMatch; IEnumerator CheckPCTime() { var ntp = new DateTime(); yield return StartCoroutine(Request(r => ntp = r)); var pc = DateTime.Now.ToLocalTime(); if ((ntp - pc).TotalSeconds < 5) { isMatch = true; } else { isMatch = false; } Debug.Log(pc + " : " + ntp + "=" + isMatch); } public DateTime GetDateTime() { var value = DateTime.Now.ToLocalTime(); if (!isMatch) { StartCoroutine(Request(r => value = r)); } return value; } }
呼び出し方法
TimeStamp.instance.GetDateTime();
以上。