PGRData/Script/matrix/xcommon/XTime.lua

360 lines
12 KiB
Lua
Raw Normal View History

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
--==============================--
--desc: 获取服务器当前时间戳
--@return 长整型时间戳,单位(秒)
--==============================--
function XTime.GetServerNowTimestamp()
local sinceStartup = CsTime.realtimeSinceStartup
return floor(ServerTimeWhenStartupAverage + sinceStartup)
end
--==============================--
--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
end