191 lines
6.1 KiB
C#
191 lines
6.1 KiB
C#
using System;
|
||
using NBC;
|
||
using UnityEngine;
|
||
|
||
namespace NBF
|
||
{
|
||
public class GameTimer
|
||
{
|
||
static GameTimer()
|
||
{
|
||
SetServerTime(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
||
}
|
||
|
||
// 游戏纪元开始时间(Unix 时间戳,毫秒)
|
||
private const long GameEpoch = 1672531200000; // 2023-01-01 00:00:00 UTC
|
||
|
||
// 时间加速比例 (1现实秒 = 15游戏秒)
|
||
private const int TimeAcceleration = 20;
|
||
|
||
//一天, 一小时, 一分钟固定时长(毫秒)
|
||
public const long DAY_MILLS = 86400000;
|
||
public const long HOUR_MILLS = 3600000;
|
||
public const long MINUTE_MILLS = 60000;
|
||
public const long SECOND_MILLS = 1000;
|
||
|
||
private static long _serverTime;
|
||
|
||
/// <summary>
|
||
/// 更新服务器时间时的unity运行时间
|
||
/// </summary>
|
||
private static float _serverTimeLocalTime;
|
||
|
||
/// <summary>
|
||
/// 当前服务器时间(ms)
|
||
/// </summary>
|
||
public static long serverTime
|
||
{
|
||
get
|
||
{
|
||
var offsetLocalTime = (long)((Time.realtimeSinceStartup - _serverTimeLocalTime) * 1000);
|
||
return _serverTime + offsetLocalTime;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 当前游戏时间
|
||
/// </summary>
|
||
public static long gameTime => RealToGameTimestamp(serverTime);
|
||
|
||
public static string gameTimeString
|
||
{
|
||
get
|
||
{
|
||
var realTime = DateTimeOffset.FromUnixTimeMilliseconds(gameTime);
|
||
return $"{realTime.Hour:D2}:{realTime.Minute:D2}";
|
||
}
|
||
}
|
||
|
||
public static DateTime ServerDateTime => ConvertUtcToDateTime(serverTime);
|
||
|
||
|
||
public static void SetServerTime(long time)
|
||
{
|
||
Log.Info($"设置服务器时间={time}");
|
||
_serverTime = time;
|
||
_serverTimeLocalTime = Time.realtimeSinceStartup;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取本地时区
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static int GetLocalTimeZoneOffset()
|
||
{
|
||
TimeZoneInfo localTimeZone = TimeZoneInfo.Local;
|
||
int offset = (int)localTimeZone.BaseUtcOffset.TotalHours;
|
||
|
||
return offset;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 现实时间戳转游戏时间戳
|
||
/// </summary>
|
||
/// <param name="realTimestamp">现实时间戳(毫秒)</param>
|
||
/// <returns>游戏时间戳(毫秒)</returns>
|
||
public static long RealToGameTimestamp(long realTimestamp)
|
||
{
|
||
long realElapsed = realTimestamp - GameEpoch;
|
||
long gameElapsed = realElapsed * TimeAcceleration;
|
||
return GameEpoch + gameElapsed;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 游戏时间戳转现实时间戳
|
||
/// </summary>
|
||
/// <param name="gameTimestamp">游戏时间戳(毫秒)</param>
|
||
/// <returns>现实时间戳(毫秒)</returns>
|
||
public static long GameToRealTimestamp(long gameTimestamp)
|
||
{
|
||
long gameElapsed = gameTimestamp - GameEpoch;
|
||
long realElapsed = gameElapsed / TimeAcceleration;
|
||
return GameEpoch + realElapsed;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 13位时间戳转化为时间
|
||
/// </summary>
|
||
/// <param name="utcTime">时间戳</param>
|
||
/// <returns></returns>
|
||
public static DateTime ConvertUtcToDateTime(long utcTime)
|
||
{
|
||
var startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Utc);
|
||
var cTime = startTime.AddTicks(utcTime * 10000);
|
||
return cTime;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 时间转化为10位时间戳
|
||
/// </summary>
|
||
/// <param name="time">获取的时间</param>
|
||
/// <returns></returns>
|
||
public static long ConvertDateTimeToUtc_10(DateTime time)
|
||
{
|
||
TimeSpan timeSpan = time.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
return Convert.ToInt64(timeSpan.TotalSeconds);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转为毫秒时间戳 13位
|
||
/// </summary>
|
||
/// <param name="time"></param>
|
||
/// <returns></returns>
|
||
public static long ConvertDateTimeToUtc(DateTime time)
|
||
{
|
||
TimeSpan timeSpan = time - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
||
return Convert.ToInt64(timeSpan.TotalMilliseconds);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将一个秒数转换成"00:00:00"格式
|
||
/// </summary>
|
||
/// <param name="second"></param>
|
||
/// <returns></returns>
|
||
public static string GetTimeStringHMD(long second)
|
||
{
|
||
int h = Mathf.FloorToInt(second / 3600f);
|
||
int m = Mathf.FloorToInt(second / 60f - h * 60f);
|
||
int s = Mathf.FloorToInt(second - m * 60f - h * 3600f);
|
||
// 直接返回格式化好的小时、分钟、秒
|
||
return string.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将一个秒数转换成"00:00"格式
|
||
/// </summary>
|
||
/// <param name="second"></param>
|
||
/// <returns></returns>
|
||
public static string GetTimeStringMD(int second)
|
||
{
|
||
if (second <= 0)
|
||
{
|
||
return "00:00";
|
||
}
|
||
|
||
float m = Mathf.FloorToInt(second / 60f);
|
||
float s = Mathf.FloorToInt(second % 60);
|
||
|
||
// 使用ZString进行高效的字符串拼接
|
||
return string.Format("{0:D2}:{1:D2}", (int)m, (int)s);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 获取游戏时间在当天的进度(0到1之间的值)
|
||
/// 0表示当天0点,1表示当天24点
|
||
/// </summary>
|
||
public static float GetGameDayProgress()
|
||
{
|
||
// 获取当天的总毫秒数
|
||
double totalMillisecondsInDay = 24 * 60 * 60 * 1000; // 86400000ms
|
||
|
||
// 计算当天已过去的毫秒数
|
||
double elapsedMilliseconds = ConvertUtcToDateTime(gameTime).TimeOfDay.TotalMilliseconds;
|
||
|
||
// 计算进度(0-1)
|
||
return (float)(elapsedMilliseconds / totalMillisecondsInDay);
|
||
}
|
||
}
|
||
} |