using System; using System.Text; using UnityEngine; public static class TimeUtility { private static DateTime s_ServerTime = DateTime.Now; private static float _checkTime = 0; /// /// 当前服务器时间 /// public static DateTime ServerNow { get { float tick = Time.realtimeSinceStartup - _checkTime; DateTime real = s_ServerTime.AddSeconds(tick); return real; } private set { s_ServerTime = value; } } ////A0 04 同步客户端时间 #tagServerDateTime 中的 CrossServerTime 为玩家在子服中收到的跨服时间 //CrossServerNow为玩家登录在跨服服务器里的通知时间, 与ILTimeUtility.ServerCrossNow(玩家在子服收到跨服的时间通知)不同 static DateTime s_CrossServerTime = DateTime.Now; static float _crossCheckTime = 0; public static DateTime CrossServerNow { get { float tick = Time.realtimeSinceStartup - _crossCheckTime; DateTime real = s_CrossServerTime.AddSeconds(tick); return real; } private set { s_CrossServerTime = value; } } /// /// 年份 /// public static int Year { get { return ServerNow.Year; } } /// /// 月份 /// public static int Month { get { return ServerNow.Month; } } /// /// 天 /// public static int Day { get { return ServerNow.Day; } } /// /// 小时 /// public static int Hour { get { return ServerNow.Hour; } } /// /// 分钟 /// public static int Minute { get { return ServerNow.Minute; } } /// /// 秒 /// public static int Second { get { return ServerNow.Second; } } // 风险点1 System.TimeZone.CurrentTimeZone.ToLocalTime 为本机, ServerNow为服务器,如果不存在同一个时区会造成时间差 // 风险点2 OriginalTime固定写死中国时区,可根据utc计算出时区,方便海外各个版本使用 /// /// 服务器起始时间 /// public static readonly DateTime OriginalTime = new DateTime(1970, 1, 1, 7, 0, 0); public static readonly DateTime ClientOriginalTime = new DateTime(1, 1, 1, 0, 0, 0); /// /// 服务器时间相比起始时间的秒数(主要方便比较) /// public static int AllSeconds { get { TimeSpan t = ServerNow - OriginalTime; return (int)t.TotalSeconds; } } //1年中的第几周,以服务端为准,python和c#算出来不一样 public static int WeekOfYear { get; private set; } public static int OpenDay { get; private set; } public static bool IsMixServer { get; private set; } public static int MixOpenDay { get; private set; } public static DayOfWeek openServerDayOfWeek; public static int OpenWeekCnt { get { var _openDay = ServerNow.AddDays(-OpenDay); var _opendayOfWeek = _openDay.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)_openDay.DayOfWeek; _openDay = _openDay.AddDays(7 - _opendayOfWeek + 1); var _openTime = new DateTime(_openDay.Year, _openDay.Month, _openDay.Day, 0, 0, 0); var _total = Mathf.Max(0, (float)ServerNow.Subtract(_openTime).TotalDays); return Mathf.CeilToInt((float)_total / 7); } } static StringBuilder stringBuilder = new StringBuilder(); public static DateTime createRoleTime { get; private set; } private static DateTime createRoleTimeTail = DateTime.Now; //从1开始 public static int CreateDays { get { return Mathf.CeilToInt((float)(ServerNow - createRoleTimeTail).TotalDays); } } public static int CreateSeconds { get { return (int)(createRoleTime - OriginalTime).TotalSeconds; } } public static event Action OnCreateRoleTimeRefresh; public static void OnRefreshCreateRoleTime(HA124_tagMCPlayerInfo _package) { if (_package.socketType == ServerType.CrossSever) { return; } createRoleTime = Convert.ToDateTime(UIHelper.GetTime(_package.CreateRoleTime)); createRoleTimeTail = new DateTime(createRoleTime.Year, createRoleTime.Month, createRoleTime.Day); if (OnCreateRoleTimeRefresh != null) { OnCreateRoleTimeRefresh(); } DebugEx.LogFormat("CreateRoleTime {0} CreateDays {1}", createRoleTimeTail, CreateDays); } public static event Action OnServerTimeRefresh; public static void OnRefreshServerTime(HA004_tagServerDateTime vNetData) { var dateTime = new DateTime(vNetData.Year, vNetData.Month, vNetData.Day, vNetData.Hour, vNetData.Minute, vNetData.Second); if (vNetData.socketType == ServerType.CrossSever) { s_CrossServerTime = dateTime; _crossCheckTime = Time.realtimeSinceStartup; } else { s_ServerTime = dateTime; _checkTime = Time.realtimeSinceStartup; if (OnServerTimeRefresh != null) { OnServerTimeRefresh(); } } TimeDownMgr.Instance.Begin(TimeDownMgr.CoolTimeType.SyncServerTime, 60, (float tick) => { SyncServerTime(); }, 60); } public static event Action OnServerOpenDayRefresh; public static void OnRefreshServerOpenDay(HA005_tagOpenServerDay package) { if (package.socketType != ServerType.CrossSever) { OpenDay = package.Day; IsMixServer = package.IsMixServer == 1; MixOpenDay = package.MixDay; openServerDayOfWeek = package.OpenWeekday == 7 ? DayOfWeek.Sunday : (DayOfWeek)package.OpenWeekday; WeekOfYear = package.WeekOfYear; } OnRefreshServerTime(new HA004_tagServerDateTime() { Year = package.NowYear, Month = package.NowMonth, Day = package.NowDay, Hour = package.NowHour, Minute = package.NowMinute, Second = package.NowSecond, MicSecond = package.NowMicSecond, socketType = package.socketType, }); if (package.socketType != ServerType.CrossSever && OnServerOpenDayRefresh != null) { OnServerOpenDayRefresh(); } } public static void SyncServerTime() { CA002_tagClientRequestServerTime pak = new CA002_tagClientRequestServerTime(); GameNetSystem.Instance.SendInfo(pak); if (GameNetSystem.Instance.crossServerSocketConnected) { GameNetSystem.Instance.SendToCrossServer(pak); } } /// /// 根据服务器下发的秒数获取时间 /// /// /// public static DateTime GetTime(uint seconds) { DateTime d = OriginalTime.AddTicks(seconds * TimeSpan.TicksPerSecond); return d; } //时:分:秒 //例子 //xx:xx:xx public static string SecondsToHMS(int _seconds) { int hours = _seconds / 3600; int mins = _seconds % 3600 / 60; int seconds = _seconds % 60; return StringUtility.Contact(hours.ToString("D2"), ":", mins.ToString("D2"), ":", seconds.ToString("D2")); } //例子;分:秒 //xx:xx public static string SecondsToMS(int _seconds) { int mins = _seconds % 3600 / 60; int seconds = _seconds % 60; return StringUtility.Contact(mins.ToString("D2"), ":", seconds.ToString("D2")); } //例子;不足的不显示 如0天0:xx:xx:,显示为xx:xx //x天xx:xx:xx秒 public static string SecondsToDHMSCHS(int _seconds) { int days = _seconds / 86400; int hours = _seconds % 86400 / 3600; int mins = _seconds % 3600 / 60; int seconds = _seconds % 60; return StringUtility.Contact(days > 0 ? days.ToString() : string.Empty, days > 0 ? Language.Get("L1074") + " " : string.Empty, hours > 0 ? hours.ToString() : string.Empty, hours > 0 ? ":" : string.Empty, mins >= 0 ? mins.ToString("D2") : string.Empty, mins >= 0 ? ":" : string.Empty, seconds >= 0 ? seconds.ToString("D2") : string.Empty, seconds >= 0 ? string.Empty : string.Empty); } //例子 //x天 //x时 //x分 最小1分 public static string SecondsToTitleDHMS(int _seconds) { int days = _seconds / 86400; if (days > 0) { return StringUtility.Contact(days, Language.Get("L1074")); } int hours = _seconds % 86400 / 3600; if (hours > 0) { return StringUtility.Contact(hours, Language.Get("Hour")); } int mins = Mathf.CeilToInt(_seconds % 3600 / 60.0f); if (mins > 0) { return StringUtility.Contact(mins, Language.Get("Minute")); } return StringUtility.Contact(1, Language.Get("Minute")); } //例子; //xx:xx:xx public static string SecondsToHMSCHSRetain(int _seconds, bool _hour = true, bool _min = true, bool _sec = true) { stringBuilder.Length = 0; int hours = _seconds / 3600; int mins = _seconds % 3600 / 60; int seconds = _seconds % 60; if (hours > 0 || _hour) { stringBuilder.Append(hours); stringBuilder.Append(":"); } if (mins > 0 || _min) { stringBuilder.Append(mins); stringBuilder.Append(":"); } if (seconds > 0 || _sec) { stringBuilder.Append(seconds); //stringBuilder.Append(":"); } return stringBuilder.ToString(); } //例子 //大于1天的显示:x天xx:xx:xx //xx:xx:xx public static string SecondsToDHMS(int _seconds) { int days = _seconds / 86400; int hours = _seconds % 86400 / 3600; int mins = _seconds % 3600 / 60; int seconds = _seconds % 60; if (days > 0) { return StringUtility.Contact(days, Language.Get("L1074"), " ", hours.ToString("D2"), ":", mins.ToString("D2"), ":", seconds.ToString("D2")); } return StringUtility.Contact(hours.ToString("D2"), ":", mins.ToString("D2"), ":", seconds.ToString("D2")); } //例子 //x天 //x时 //x分x秒 //x秒 public static string SecondsToConsumeRebate(int _seconds) { float days = (float)_seconds / 86400; float hours = (float)_seconds % 86400 / 3600; int mins = _seconds % 3600 / 60; float seconds = (float)_seconds % 60; if (days >= 1) { return StringUtility.Contact(Mathf.CeilToInt(days), Language.Get("L1074")); } else if (hours >= 1) { return StringUtility.Contact(Mathf.CeilToInt(hours), Language.Get("Hour")); } else if (mins >= 1) { return StringUtility.Contact(mins, Language.Get("Minute"), seconds, Language.Get("RealmWin_Bewrite_35")); } else { return StringUtility.Contact(seconds, Language.Get("RealmWin_Bewrite_35")); } } /// /// 获取一天的0点时间 /// /// /// public static DateTime GetDayStartTime(int year, int month, int day) { return new DateTime(year, month, day); } /// /// 获取当天的0点时间 /// /// public static DateTime GetTodayStartTime() { var now = ServerNow; return new DateTime(now.Year, now.Month, now.Day); } /// /// 获取下一个凌晨5点的时间 /// /// public static DateTime GetNext5Time() { var now = ServerNow; if (now.Hour < 5) { return new DateTime(now.Year, now.Month, now.Day, 5, 0, 0); } return new DateTime(now.Year, now.Month, now.Day, 5, 0, 0).AddDays(1); } //开服天结束倒计时;单位秒 public static int GetRemindTimeByOpenDay(int days) { if (days <= OpenDay) return 0; return (days - OpenDay) * 86400 - (int)(ServerNow - GetTodayStartTime()).TotalSeconds; } //获得已过了多少天(0点过天整数,第一天为0) // seconds 为时间戳 public static int GetPassDays(int seconds) { DateTime d = OriginalTime.AddTicks(seconds * TimeSpan.TicksPerSecond); DateTime startTime = new DateTime(d.Year, d.Month, d.Day); return (ServerNow - startTime).Days; } }