Skip to content

Instantly share code, notes, and snippets.

@gamebox777
Last active September 4, 2019 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamebox777/05123f1aefbd8be23a258b9aaae19d97 to your computer and use it in GitHub Desktop.
Save gamebox777/05123f1aefbd8be23a258b9aaae19d97 to your computer and use it in GitHub Desktop.
///
/// 時間をweb APIから取得
///
using UnityEngine;
using System;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
[Serializable]
public class WorldClock
{
public string datetime;
public string currentDateTime;
public string utcOffset;
public string dayOfTheWeek;
public string timeZoneName;
public double currentFileTime;
public string ordinalDate;
public string serviceResponse;
}
///
///世界時計のインスタンス
///
public static class WorldClockBuilder
{
public static string errorMessage = String.Empty; // 失敗した時のエラーメッセージ
private static int connectrionRetries; // リトライ回数
public static WorldClock instance; // 世界時計のインスタンス
public static DateTime worldClockDate; // Global DateTime
public static State currentState; // ステート
public enum State
{
NotInitialized,
Initializing, Initialized, FailedToInitialize
};
public static IEnumerator InitializeWorldClock(string worldClockUrl, int maxRetries, string worldClockFMT)
{
currentState = State.Initializing;
string result = String.Empty;
while (connectrionRetries < maxRetries)
{
WWW www = new WWW(worldClockUrl);
while (!www.isDone) { yield return null; }
if (!string.IsNullOrEmpty(www.error))
{
connectrionRetries++;
Debug.LogError("世界時計の読み込みエラー。 接続を再試行しています " + connectrionRetries);
errorMessage = www.error;
}
else
{
result = www.text;
break;
}
}
if (!string.IsNullOrEmpty(result))
{
var clockJson = result;
// JSON形式で読み込み
var worldClock = JsonUtility.FromJson<WorldClock>(clockJson);
//世界時計のインスタンス保存
instance = worldClock;
var dateTimeStr = worldClock.currentDateTime;
if (string.IsNullOrEmpty(worldClock.currentDateTime))
dateTimeStr = worldClock.datetime;
worldClockDate = DateTime.ParseExact(dateTimeStr, worldClockFMT, CultureInfo.InvariantCulture);
// 世界時計は秒をカウントしないのでローカルマシンから秒を獲得
worldClockDate = worldClockDate.AddSeconds(DateTime.Now.Second);
var time = string.Format("{0:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}", worldClockDate.Year, worldClockDate.Month, worldClockDate.Day, worldClockDate.Hour, worldClockDate.Minute, worldClockDate.Second);
Debug.Log("世界時間: " + time);
currentState = State.Initialized;
}
else
{
Debug.LogError("世界時間読み込みエラー:" + errorMessage);
currentState = State.FailedToInitialize;
}
}
}
/// <summary>
/// 世界時計取得テスト
/// </summary>
public class WorldClockTest : MonoBehaviour
{
public int instanceId;
public bool isSingleton = true; // チェックを入れるとシングルトン
public string worldClockUrl = "http://worldtimeapi.org/api/timezone/America/New_York"; // 時間をJSON形式で取得するAPI
public string worldClockFMT = "yyyy-MM-dd'T'HH:mm:ss.ffffffzzz"; // 時間フォーマット
public bool useWorldClockApi = true; // 世界時間APIを使う
public WorldClock worldClock; // 世界時間オブジェクト
public string errorMessage; // エラーメッセージ
public bool isErrorConnect; // ネット接続中にエラーが発生したか
public DateTime now; // 取得した時間。(世界時間 or デバイスの時間)
public int maxRetries = 3; // 取得エラー最大リトライ回数
//タイマーが初期化されるとき。 発生した場合にエラーメッセージを送信します。 World Clock APIを使用している場合、このデリゲートを待つ必要があります
public delegate void OnInitialize(bool error = false, string errorMessage = "");
public OnInitialize onInitialize;
protected bool isInitialized = false;
/// <summary>
/// 現在のDateTimeを初期化
/// 世界時計初期化
/// </summary>
/// <returns></returns>
public IEnumerator InitializeDate()
{
if ( useWorldClockApi )
{
if (WorldClockBuilder.currentState == WorldClockBuilder.State.NotInitialized)
{
// 世界時間初期化
yield return StartCoroutine(WorldClockBuilder.InitializeWorldClock(worldClockUrl, maxRetries, worldClockFMT));
}
else if (WorldClockBuilder.currentState == WorldClockBuilder.State.Initializing)
{
// 世界時間初期化中なので終了するまで待機
while (WorldClockBuilder.currentState == WorldClockBuilder.State.Initializing)
yield return null;
}
if (WorldClockBuilder.currentState == WorldClockBuilder.State.Initialized)
{
worldClock = WorldClockBuilder.instance;
now = WorldClockBuilder.worldClockDate;
isInitialized = true;
}
else if (WorldClockBuilder.currentState == WorldClockBuilder.State.FailedToInitialize)
{
isErrorConnect = true;
errorMessage = WorldClockBuilder.errorMessage;
}
}
else
{
//デバイス時間の取得
now = DateTime.Now;
isInitialized = true;
}
}
/// <summary>
/// 時間初期化
/// </summary>
/// <returns></returns>
private IEnumerator InitializeTimer()
{
yield return StartCoroutine( InitializeDate() );
if ( isErrorConnect )
{
if (onInitialize != null) { onInitialize(true, errorMessage); }
}
else
{
if (onInitialize != null) { onInitialize(); }
}
}
// Start is called before the first frame update
void Start()
{
StartCoroutine( InitializeTimer() );
}
// Update is called once per frame
void Update()
{
}
void OnGUI()
{
string str = String.Empty;
if (useWorldClockApi) { str = "世界時計"; }
else { str = "デバイス時計"; }
string time = string.Format("{0:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}", now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
GUI.Label(new Rect(20, 20, 200, 30), str + ":" +time);
if (GUI.Button(new Rect(50, 50, 100, 50),"時間更新"))
{
WorldClockBuilder.currentState = WorldClockBuilder.State.NotInitialized;
StartCoroutine(InitializeTimer());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment