Last active
September 4, 2019 10:57
-
-
Save gamebox777/05123f1aefbd8be23a258b9aaae19d97 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// | |
/// 時間を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