カウントダウンアプリをつくっていますが,各自のスマホの時間がバラバラなので,ntpから差分とった時刻で正確な時間を出すようにしてみました.
修正中ですが,概ねこれで作動します.
元ネタはこれ→ http://ftvoid.com/blog/post/847
HTML5ならもう少し簡単だったのですが,,
using UnityEngine; using System; using System.Collections; using System.Net; using System.Net.Sockets; using System.Threading; using UnityEngine.UI;//use unity gui // NTP同期時刻を管理するクラス public class NtpDate : MonoBehaviour { private DateTime ntpDate; // NTP同期時刻 private float rcvAppDate; // NTP通信時のアプリ時刻 private IPEndPoint ipAny; private UdpClient sock; private Thread thread; private volatile bool threadRunning = false; private byte[] rcvData; public string myString; //for time display private DateTime endDate; //for end date public Transform myButton; //get button object public Text countText; //Text用変数 private TimeSpan zure; // 初期化 void Start() { // リクエスト実行 SyncDate(); // 時刻表示(デバッグ用) StartCoroutine(ShowSyncDate()); //Debug.Log (System.DateTime.Now); } // 同期時刻の表示 private IEnumerator ShowSyncDate() { while ( true ) { yield return new WaitForSeconds(0.1f);//0.5f timeCheck ();// do timeCheck() every 1 second //if ( Date == false ) { if ( Date == null ) { Debug.Log("Time is not received."); } else { //Debug.Log("Receive date : " + Date.ToString()); // Debug.Log (DateTime.Now);// DateTime.Now is confiured time } } } /// for GUI my add public void timeCheck(){ endDate = new DateTime(2016, 4, 2, 18,30,00); //本番用 // endDate = new DateTime(2016, 2, 4, 12,30,00);//for test TimeSpan sabun = endDate - DateTime.Now; //compare now time and end time // Debug.Log ("before" + sabun); // Debug.Log ("after" + (sabun - zure)); //int result = TimeSpan.Compare(endDate, DateTime.Now);// cant use sabun = sabun - zure;//zure naosu if (sabun.Days <= 0 && sabun.Hours <= 0 && sabun.Minutes <= 0 && sabun.Seconds <= 0) { //sabun is all zero and minus myString = "Light It Up Blue!"; //message of button countText.text = myString; //put text to GUItext myButton.GetComponent<Toggle>().interactable = true; //unlock the button } else { myString = string.Format ("{0:00}D{1:00}H{2:00}M{3:00}S", sabun.Days, sabun.Hours, sabun.Minutes, sabun.Seconds);//string format countText.text = myString; //time remaining myButton.GetComponent<Toggle>().interactable = false; //lock button before last time } } public void Update(){ // timeCheck (); } // アプリケーション終了時処理 void OnApplicationQuit() { if ( thread != null ) { thread.Abort(); } if ( sock != null ) { sock.Close(); } } // 時刻同期を行う public void SyncDate() { // リクエスト実行 threadRunning = true; thread = new Thread(new ThreadStart(Request)); thread.Start(); // リクエスト待機コルーチン実行 StartCoroutine(WaitForRequest()); Debug.Log("Thread is started."); } // NTPサーバに対してリクエストを実行する private void Request() { // ソケットを開く ipAny = new IPEndPoint(IPAddress.Any, 123); // sock = new UdpClient(ipAny); sock = new UdpClient(); // リクエスト送信 byte[] sndData = new byte[48]; sndData[0] = 0xB; sock.Send(sndData, sndData.Length, "ntp.jst.mfeed.ad.jp", 123); // データ受信 rcvData = sock.Receive(ref ipAny); // 実行中フラグクリア threadRunning = false; } // リクエスト待機コルーチン private IEnumerator WaitForRequest() { // リクエスト終了まで待機 while ( threadRunning ) { yield return 0; } // アプリ時刻保存 rcvAppDate = Time.realtimeSinceStartup; Debug.Log (rcvAppDate); // 受信したバイナリデータをDateTime型に変換 ntpDate = new DateTime(1900, 1, 1); var high = (double)BitConverter.ToUInt32(new byte[] { rcvData[43], rcvData[42], rcvData[41], rcvData[40] }, 0); var low = (double)BitConverter.ToUInt32(new byte[] { rcvData[47], rcvData[46], rcvData[45], rcvData[44] }, 0); ntpDate = ntpDate.AddSeconds(high + low / UInt32.MaxValue); // UTC→ローカル日時に変換 ntpDate = ntpDate.ToLocalTime(); zure = Date - DateTime.Now; Debug.Log ("zure" + zure); } // NTP同期時刻 public DateTime Date { get { return ntpDate.AddSeconds(Time.realtimeSinceStartup - rcvAppDate); } } }