Files
Fishing2/Assets/Scripts/Demo/GameTimer.cs
2025-08-29 09:11:08 +08:00

191 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 = 200;
//一天, 一小时, 一分钟固定时长(毫秒)
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);
}
}
}