2023-07-14 19:35:33 +00:00
|
|
|
|
XTime = XTime or {}
|
|
|
|
|
|
|
|
|
|
local floor = math.floor
|
|
|
|
|
local CsTime = CS.UnityEngine.Time
|
|
|
|
|
|
|
|
|
|
local ServerTimeWhenStartupList = {} --客户端启动时,服务器的时间戳
|
|
|
|
|
local ServerTimeMaxCount = 10 --保存服务端时间的最大个数
|
|
|
|
|
local CurrentSaveIndex = 1 --当前保存到的下标
|
|
|
|
|
local ServerTimeWhenStartupAverage = 0 --客户端启动时,服务器的时间戳平局值
|
|
|
|
|
|
|
|
|
|
local PingTimeList = {}
|
|
|
|
|
local PingTimeIndex = 0
|
|
|
|
|
local PingTimeLength = 10
|
|
|
|
|
|
|
|
|
|
-- 一星期中的第几天 (3)[1 - 6 = 星期天 - 星期六]
|
|
|
|
|
local WeekOfDay = {
|
|
|
|
|
Sun = 0,
|
|
|
|
|
Mon = 1,
|
|
|
|
|
Tues = 2,
|
|
|
|
|
Wed = 3,
|
|
|
|
|
Thur = 4,
|
|
|
|
|
Fri = 5,
|
|
|
|
|
Sat = 6,
|
|
|
|
|
NorSun = 7
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
local WeekOfDayIndex = {
|
|
|
|
|
[WeekOfDay.Mon] = 1,
|
|
|
|
|
[WeekOfDay.Tues] = 2,
|
|
|
|
|
[WeekOfDay.Wed] = 3,
|
|
|
|
|
[WeekOfDay.Thur] = 4,
|
|
|
|
|
[WeekOfDay.Fri] = 5,
|
|
|
|
|
[WeekOfDay.Sat] = 6,
|
|
|
|
|
[WeekOfDay.Sun] = 7,
|
|
|
|
|
[WeekOfDay.NorSun] = 7
|
|
|
|
|
}
|
|
|
|
|
local WeekLength = 7
|
|
|
|
|
local sec_of_a_day = 24 * 60 * 60
|
|
|
|
|
local sec_of_one_hour = 60 * 60
|
|
|
|
|
local sec_of_refresh_time = 7 * 60 * 60
|
2024-09-01 20:49:41 +00:00
|
|
|
|
XTime.Seconds = {
|
|
|
|
|
Day = sec_of_a_day --86400
|
|
|
|
|
}
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
|
|
--==============================--
|
|
|
|
|
--desc: 获取服务器当前时间戳
|
|
|
|
|
--@return 长整型时间戳,单位(秒)
|
|
|
|
|
--==============================--
|
|
|
|
|
function XTime.GetServerNowTimestamp()
|
|
|
|
|
local sinceStartup = CsTime.realtimeSinceStartup
|
|
|
|
|
return floor(ServerTimeWhenStartupAverage + sinceStartup)
|
|
|
|
|
end
|
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
|
--==============================
|
|
|
|
|
---@desc 获取本地时间戳
|
|
|
|
|
---@return 长整型时间戳,单位(秒)
|
|
|
|
|
--==============================
|
|
|
|
|
function XTime.GetLocalNowTimestamp()
|
|
|
|
|
return CS.XDateUtil.GetNowTimestamp()
|
|
|
|
|
end
|
|
|
|
|
|
2023-07-14 19:35:33 +00:00
|
|
|
|
--==============================--
|
|
|
|
|
--desc: 同步时间
|
|
|
|
|
--@serverTime: 服务器时间
|
|
|
|
|
--@reqTime: 发起请求时间
|
|
|
|
|
--@resTime: 收到响应时间
|
|
|
|
|
--==============================--
|
|
|
|
|
function XTime.SyncTime(serverTime, reqTime, resTime)
|
|
|
|
|
local startup = (reqTime + resTime) * 0.5
|
|
|
|
|
local span = serverTime - startup
|
|
|
|
|
|
|
|
|
|
if CurrentSaveIndex > ServerTimeMaxCount then
|
|
|
|
|
CurrentSaveIndex = CurrentSaveIndex - ServerTimeMaxCount
|
|
|
|
|
end
|
|
|
|
|
ServerTimeWhenStartupList[CurrentSaveIndex] = span
|
|
|
|
|
CurrentSaveIndex = CurrentSaveIndex + 1
|
|
|
|
|
|
|
|
|
|
local count = #ServerTimeWhenStartupList
|
|
|
|
|
local total = 0
|
|
|
|
|
for _, v in ipairs(ServerTimeWhenStartupList) do
|
|
|
|
|
total = total + v
|
|
|
|
|
end
|
|
|
|
|
ServerTimeWhenStartupAverage = total / count
|
|
|
|
|
|
|
|
|
|
local gap = resTime - reqTime
|
|
|
|
|
PingTimeIndex = (PingTimeIndex % PingTimeLength) + 1
|
|
|
|
|
PingTimeList[PingTimeIndex] = gap
|
|
|
|
|
-- print(" ======= ping(ms) ... gap: " .. tostring(gap) .. ", avr:" .. tostring(XTime.GetPingTime()) .. ", i:" .. tostring(PingTimeIndex) .. ", t:" .. tostring(CS.UnityEngine.Time.realtimeSinceStartup))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 获取网络延时 单位: ms
|
|
|
|
|
function XTime.GetPingTime()
|
|
|
|
|
if #PingTimeList == 0 then
|
|
|
|
|
return 0
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local total = 0
|
|
|
|
|
for _, v in ipairs(PingTimeList) do
|
|
|
|
|
total = total + v
|
|
|
|
|
end
|
|
|
|
|
return math.floor(total * 1000) / #PingTimeList
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function XTime.ClearPingTime()
|
|
|
|
|
PingTimeList = {}
|
|
|
|
|
PingTimeIndex = 0
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--==============================--
|
|
|
|
|
--desc: 时间字符串转服务器时区时间戳
|
|
|
|
|
--@dateTimeString: 时间字符串
|
|
|
|
|
--@return 转失败返回nil
|
|
|
|
|
--==============================--
|
|
|
|
|
function XTime.ParseToTimestamp(dateTimeString)
|
|
|
|
|
if dateTimeString == nil or dateTimeString == "" then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local success, timestamp = CS.XDateUtil.TryParseToTimestamp(dateTimeString)
|
|
|
|
|
if not success then
|
|
|
|
|
XLog.Error("XTime.TryParseToTimestamp parse to timestamp failed. try use ParseToTimestampMDY: " .. tostring(dateTimeString))
|
|
|
|
|
return XTime.ParseToTimestampMDY(dateTimeString)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return timestamp
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function XTime.ParseToTimestampMDY(dateTimeString)
|
|
|
|
|
local arr = string.Split(dateTimeString, " ")
|
|
|
|
|
local date = arr[1]
|
|
|
|
|
local time = arr[2]
|
|
|
|
|
local dateArr = string.Split(date, "/")
|
|
|
|
|
local m = dateArr[1]
|
|
|
|
|
local d = dateArr[2]
|
|
|
|
|
local y = dateArr[3]
|
|
|
|
|
dateTimeString = y .. "/" .. m .. "/" .. d .. " " .. time
|
|
|
|
|
local success, timestamp = CS.XDateUtil.TryParseToTimestamp(dateTimeString)
|
|
|
|
|
if not success then
|
|
|
|
|
XLog.Error("XTime.TryParseToTimestamp parse to timestamp failed. invalid time argument: " .. tostring(dateTimeString))
|
|
|
|
|
return -- 该类在CS中不存在,且在1.18版本出现时区格式问题
|
|
|
|
|
-- return CS.XDate.GetTime(dateTimeString)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return timestamp
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--时间戳转utc时间字符串
|
|
|
|
|
function XTime.TimestampToUtcDateTimeString(timestamp, format)
|
|
|
|
|
format = format or "yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
local dt = CS.XDateUtil.GetUtcDateTime(timestamp)
|
|
|
|
|
return dt:ToString(format)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--时间戳转设备本地时间字符串
|
|
|
|
|
function XTime.TimestampToLocalDateTimeString(timestamp, format)
|
|
|
|
|
format = format or "yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
local dt = CS.XDateUtil.GetLocalDateTime(timestamp)
|
|
|
|
|
return dt:ToString(format)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--时间戳转游戏指定时区时间字符串
|
|
|
|
|
function XTime.TimestampToGameDateTimeString(timestamp, format)
|
|
|
|
|
format = format or "yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
local dt = CS.XDateUtil.GetGameDateTime(timestamp)
|
|
|
|
|
return dt:ToString(format)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- c#星期枚举转整形数
|
|
|
|
|
function XTime.DayOfWeekToInt(dayOfWeek, isNormlSunDay)
|
|
|
|
|
if dayOfWeek == CS.System.DayOfWeek.Sunday then
|
|
|
|
|
return isNormlSunDay and 7 or 0
|
|
|
|
|
elseif dayOfWeek == CS.System.DayOfWeek.Monday then
|
|
|
|
|
return 1
|
|
|
|
|
elseif dayOfWeek == CS.System.DayOfWeek.Tuesday then
|
|
|
|
|
return 2
|
|
|
|
|
elseif dayOfWeek == CS.System.DayOfWeek.Wednesday then
|
|
|
|
|
return 3
|
|
|
|
|
elseif dayOfWeek == CS.System.DayOfWeek.Thursday then
|
|
|
|
|
return 4
|
|
|
|
|
elseif dayOfWeek == CS.System.DayOfWeek.Friday then
|
|
|
|
|
return 5
|
|
|
|
|
else
|
|
|
|
|
return 6
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--获取今天时间
|
|
|
|
|
function XTime.GetTodayTime(hour, min, sec)
|
|
|
|
|
hour = hour or 0
|
|
|
|
|
min = min or 0
|
|
|
|
|
sec = sec or 0
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
local dt = CS.XDateUtil.GetGameDateTime(nowTime)
|
|
|
|
|
return dt.Date:AddHours(hour):AddMinutes(min):AddSeconds(sec):ToTimestamp()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function XTime.GeyServerTime(hour, min, sec)
|
|
|
|
|
hour = hour or 0
|
|
|
|
|
min = min or 0
|
|
|
|
|
sec = sec or 0
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
local dt = CS.XDateUtil.GetGameDateTime(nowTime)
|
|
|
|
|
dt = dt.Date;
|
|
|
|
|
dt = dt:AddSeconds(sec)
|
|
|
|
|
dt = dt:AddMinutes(min)
|
|
|
|
|
dt = dt:AddHours(hour)
|
|
|
|
|
return dt:ToTimestamp()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 获取距离下一个星期x的时间,默认每周第一天为周一
|
|
|
|
|
function XTime.GetNextWeekOfDayStartWithMon(weekOfDay, offsetTime)
|
|
|
|
|
local needTime
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
local dateTime = CS.XDateUtil.GetGameDateTime(nowTime)
|
|
|
|
|
local weekZero = CS.XDateUtil.GetFirstDayOfThisWeek(dateTime):ToTimestamp()
|
|
|
|
|
|
|
|
|
|
local resetTime = (WeekOfDayIndex[weekOfDay] - 1) * sec_of_a_day + offsetTime + weekZero
|
|
|
|
|
if nowTime < resetTime then
|
|
|
|
|
needTime = resetTime - nowTime
|
|
|
|
|
else
|
|
|
|
|
needTime = WeekLength * sec_of_a_day - (nowTime - resetTime)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return needTime
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 获取最近一个未到达的星期X的服务器更新时间
|
|
|
|
|
function XTime.GetSeverNextWeekOfDayRefreshTime(weekOfDay)
|
|
|
|
|
local needTime = XTime.GetNextWeekOfDayStartWithMon(weekOfDay, sec_of_refresh_time)
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
return nowTime + needTime
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 获取服务器当天5点更新时间戳
|
|
|
|
|
function XTime.GetSeverTodayFreshTime()
|
|
|
|
|
local now = XTime.GetServerNowTimestamp()
|
|
|
|
|
local dateTime = CS.XDateUtil.GetGameDateTime(now)
|
|
|
|
|
local dayZero = dateTime.Date:ToTimestamp()
|
|
|
|
|
|
|
|
|
|
return dayZero + sec_of_refresh_time
|
|
|
|
|
end
|
|
|
|
|
--=========================
|
|
|
|
|
--获取服务器当天目标时间的时间戳
|
|
|
|
|
--oclock : 目标时间,例如晚上8点为20, 8点半为 20.5
|
|
|
|
|
--=========================
|
|
|
|
|
function XTime.GetServerTodayTargetTime(oclock)
|
|
|
|
|
local now = XTime.GetServerNowTimestamp()
|
|
|
|
|
local dateTime = CS.XDateUtil.GetGameDateTime(now)
|
|
|
|
|
local dayZero = dateTime.Date:ToTimestamp()
|
|
|
|
|
return dayZero + (oclock * sec_of_one_hour)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 获取服务器明天5点更新时间戳
|
|
|
|
|
function XTime.GetSeverTomorrowFreshTime()
|
|
|
|
|
local dayFreshTime = XTime.GetSeverTodayFreshTime()
|
|
|
|
|
return dayFreshTime + sec_of_a_day
|
|
|
|
|
end
|
|
|
|
|
--=========================
|
|
|
|
|
--获取服务器当天目标时间的时间戳
|
|
|
|
|
--oclock : 目标时间(例:晚上8点 = 20, 晚上8点30分 = 20.5)
|
|
|
|
|
--=========================
|
|
|
|
|
function XTime.GetServerTomorrowTargetTime(oclock)
|
|
|
|
|
local dayFreshTime = XTime.GetServerTodayTargetTime(oclock)
|
|
|
|
|
return dayFreshTime + sec_of_a_day
|
|
|
|
|
end
|
|
|
|
|
-- 获取服务器昨天5点更新时间戳
|
|
|
|
|
function XTime.GetSeverYesterdayFreshTime()
|
|
|
|
|
local dayFreshTime = XTime.GetSeverTodayFreshTime()
|
|
|
|
|
return dayFreshTime - sec_of_a_day
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--获取服务器下一次5点更新时间戳
|
|
|
|
|
function XTime.GetSeverNextRefreshTime()
|
|
|
|
|
local nextRefreshTime
|
|
|
|
|
|
|
|
|
|
local dayRefreshTime = XTime.GetSeverTodayFreshTime()
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
nextRefreshTime = nowTime > dayRefreshTime and XTime.GetSeverTomorrowFreshTime() or dayRefreshTime
|
|
|
|
|
|
|
|
|
|
return nextRefreshTime
|
|
|
|
|
end
|
|
|
|
|
--=========================
|
|
|
|
|
--获取服务器下一次目标时间的时间戳
|
|
|
|
|
--oclock : 目标时间(例:晚上8点 = 20, 晚上8点30分 = 20.5)
|
|
|
|
|
--=========================
|
|
|
|
|
function XTime.GetServerNextTargetTime(oclock)
|
|
|
|
|
local nextTargetTime
|
|
|
|
|
local dayTargetTime = XTime.GetServerTodayTargetTime(oclock)
|
|
|
|
|
local nowTime = XTime.GetServerNowTimestamp()
|
|
|
|
|
nextTargetTime = nowTime > dayTargetTime and XTime.GetServerTomorrowTargetTime(oclock) or dayTargetTime
|
|
|
|
|
return nextTargetTime
|
|
|
|
|
end
|
|
|
|
|
--=========================
|
|
|
|
|
--获取服务器到下一次目标时间的剩余时间(单位秒)
|
|
|
|
|
--oclock : 目标时间(例:晚上8点 = 20, 晚上8点30分 = 20.5)
|
|
|
|
|
--=========================
|
|
|
|
|
function XTime.GetServerLeftTimeToTargetTime(oclock)
|
|
|
|
|
local nextTargetTime = XTime.GetServerNextTargetTime(oclock)
|
|
|
|
|
local now = XTime.GetServerNowTimestamp()
|
|
|
|
|
return nextTargetTime - now
|
|
|
|
|
end
|
|
|
|
|
-- 判断服务器当下是否是周末
|
|
|
|
|
function XTime.CheckWeekend()
|
|
|
|
|
local now = XTime.GetServerNowTimestamp()
|
|
|
|
|
local weekday = XTime.GetWeekDay(now, false)
|
|
|
|
|
|
|
|
|
|
if weekday == WeekOfDay.Sun then
|
|
|
|
|
return true
|
|
|
|
|
elseif weekday == WeekOfDay.Sat then
|
|
|
|
|
local todayFreshTime = XTime.GetSeverTodayFreshTime()
|
|
|
|
|
return now >= todayFreshTime
|
|
|
|
|
elseif weekday == WeekOfDay.Mon then
|
|
|
|
|
local todayFreshTime = XTime.GetSeverTodayFreshTime()
|
|
|
|
|
return now < todayFreshTime
|
|
|
|
|
else
|
|
|
|
|
return false
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- 判断时间戳是周几
|
|
|
|
|
function XTime.GetWeekDay(time, isNormlSunDay)
|
|
|
|
|
local dateTime = CS.XDateUtil.GetGameDateTime(time)
|
|
|
|
|
local weekday = XTime.DayOfWeekToInt(dateTime.DayOfWeek, isNormlSunDay)
|
|
|
|
|
return weekday
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--获取一个时间戳的当天刷新的时间
|
|
|
|
|
function XTime.GetTimeDayFreshTime(time)
|
|
|
|
|
local todayRefreshTime
|
|
|
|
|
|
|
|
|
|
local dateTime = CS.XDateUtil.GetGameDateTime(time)
|
|
|
|
|
local dayZero = dateTime.Date:ToTimestamp()
|
|
|
|
|
todayRefreshTime = dayZero + sec_of_refresh_time
|
|
|
|
|
|
|
|
|
|
return todayRefreshTime
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function XTime.GetWeekDayText(time)
|
|
|
|
|
local weekDay = XTime.GetWeekDay(time, true)
|
|
|
|
|
if weekDay == 1 then
|
|
|
|
|
return CSXTextManagerGetText("Monday")
|
|
|
|
|
elseif weekDay == 2 then
|
|
|
|
|
return CSXTextManagerGetText("Tuesday")
|
|
|
|
|
elseif weekDay == 3 then
|
|
|
|
|
return CSXTextManagerGetText("Wednesday")
|
|
|
|
|
elseif weekDay == 4 then
|
|
|
|
|
return CSXTextManagerGetText("Thursday")
|
|
|
|
|
elseif weekDay == 5 then
|
|
|
|
|
return CSXTextManagerGetText("Friday")
|
|
|
|
|
elseif weekDay == 6 then
|
|
|
|
|
return CSXTextManagerGetText("Saturday")
|
|
|
|
|
elseif weekDay == 7 then
|
|
|
|
|
return CSXTextManagerGetText("Sunday")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--判断两个时间戳是否在同一天
|
|
|
|
|
function XTime.IsToday(formTime, toTime)
|
|
|
|
|
local formDateTime = CS.XDateUtil.GetGameDateTime(formTime)
|
|
|
|
|
local toDateTime = CS.XDateUtil.GetGameDateTime(toTime)
|
|
|
|
|
|
|
|
|
|
local formDay = formDateTime.Day
|
|
|
|
|
local formMonth = formDateTime.Month
|
|
|
|
|
local formYear = formDateTime.Year
|
|
|
|
|
|
|
|
|
|
local toDay = toDateTime.Day
|
|
|
|
|
local toMonth = toDateTime.Month
|
|
|
|
|
local toYear = toDateTime.Year
|
|
|
|
|
|
|
|
|
|
return formDay == toDay and formMonth == toMonth and formYear == toYear
|
2024-09-01 20:49:41 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
---判断今天距某个时间戳隔了多少天 正为已过X天 负为还有X天
|
|
|
|
|
---@param toTime number|nil
|
|
|
|
|
---@param isBaseServer boolean
|
|
|
|
|
---@return number
|
|
|
|
|
function XTime.GetDayCountUntilTime(toTime, isBaseServer)
|
|
|
|
|
if toTime == nil then
|
|
|
|
|
return 0
|
|
|
|
|
end
|
|
|
|
|
local from_time = XTime.GetServerNowTimestamp()
|
|
|
|
|
local to_Time = isBaseServer and XTime.GetTimeDayFreshTime(toTime) or toTime
|
|
|
|
|
local fromDateTime = CS.XDateUtil.GetGameDateTime(from_time)
|
|
|
|
|
local toDateTime = CS.XDateUtil.GetGameDateTime(to_Time)
|
|
|
|
|
local fromSpan = CS.System.TimeSpan(fromDateTime.Ticks)
|
|
|
|
|
local toSpan = CS.System.TimeSpan(toDateTime.Ticks)
|
|
|
|
|
return math.floor(fromSpan.TotalDays - toSpan.TotalDays)
|
|
|
|
|
-- 服务端刷新时间为基准点
|
|
|
|
|
end
|