c1_lua/lua/app/common/time.lua
2025-09-25 16:04:15 +08:00

393 lines
13 KiB
Lua
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.

local Time = {
timeZoneOffset = 0,
differenceTime = 0,
todayTime = 0,
}
local SECONDS_PRE_DAY = 86400
local SECONDS_PRE_HOUR = 3600
local SECONDS_PRE_MINUTE = 60
local DAY_PER_HOUR = 24
local DAY_PRE_WEEK = 7
local ZERO_TIME_STR = "00:00:00"
local ZERO_TIME_STR_2 = "00:00"
local UnityTime = CS.UnityEngine.Time
-- 获取时间格式(时间戳转本地时间格式)
function Time:getTimeFormat(timestamp)
return os.date('*t', timestamp)
end
-- 获取时间格式(时间戳转世界时间格式)
function Time:getTimeFormatUTC(timestamp)
return os.date('!*t', timestamp)
end
-- 获取服务器的当前时间戳当前服务器是UTC-0
function Time:getServerTime()
if not self.serverTime then
return os.time()
end
return self.serverTime + self.differenceTime + GFunc.getTickCount()
end
-- 获取服务器的转本地时区的当前时间戳
function Time:getServerTimeLocal()
return self:getServerTime() + self:getTimeZoneOffset() * SECONDS_PRE_HOUR
end
-- 获取服务器的当前时间戳(毫秒级)
function Time:getServerTime2()
if not self.serverTime2 then
return os.time() * 1000
end
return self.serverTime2 + self.differenceTime2 + GFunc.getTickCount2()
end
function Time:getRealtimeSinceStartup()
return UnityTime.realtimeSinceStartup
end
-- 获取客户端时间戳
-- function Time:getClientTime()
-- return os.time()
-- end
-- 得到特定时间的时间戳
function Time:getCertainTime(data)
local year = data.year or 0
local month = data.month or 0
local day = data.day or 0
local hour = data.hour or 0
local minute = data.minute or 0
local second = data.second or 0
return os.time({ day = day, month = month, year = year, hour = hour, min = minute, sec = second })
end
-- 得到特定时间的时间戳
function Time:getCertainTimeByStr(timeStr)
-- "2022-08-9 00:00:00"
if type(timeStr) ~= "string" then
return 0
end
timeStr = string.trim(timeStr)
local timeTab = {}
for i, v in string.gmatch(timeStr, "%d+") do
-- print(i, v)
table.insert(timeTab, i)
end
local year = timeTab[1]
local month = timeTab[2]
local day = timeTab[3]
local hour = timeTab[4]
local minute = timeTab[5]
local second = timeTab[6]
local timeStr = { day = day, month = month, year = year, hour = hour, min = minute, sec = second }
local time = Time:getCertainTime(timeStr) + Time:getTimeZoneOffset() * SECONDS_PRE_HOUR
return math.floor(time)
end
-- 格式化时间返回os.data(finalTime)
function Time:formatTimeExact(time)
local endTime = self:getServerTime() + time
return self:getTimeFormat(endTime)
end
function Time:updateServerTimeToday(todayTime)
todayTime = todayTime or 0
self.todayTime = todayTime // 1000
end
function Time:updateServerTime(serverTime)
self.serverTime = (serverTime or 0) // 1000
self.serverTime2 = serverTime or 0 -- 毫秒级
self.differenceTime = -GFunc.getTickCount()
self.differenceTime2 = -GFunc.getTickCount2()
if EDITOR_MODE then
Logger.log("updateServerTime:%s", self.differenceTime)
end
end
function Time:updateByServer(serverTime, todayTime)
self:updateServerTime(serverTime)
self:updateServerTimeToday(todayTime)
end
function Time:setServerTimeZone(timeZone)
self.timeZoneOffset = math.floor(timeZone - self:getClientTimeZone())
self.serverTimeZone = timeZone
end
function Time:getClientTimeZone()
local now = os.time()
local utcdate = os.date("!*t", now)
local localdate = os.date("*t", now)
localdate.isdst = false
return os.difftime(os.time(localdate), os.time(utcdate)) / SECONDS_PRE_HOUR
end
function Time:getTimeZoneOffset()
return self.timeZoneOffset
end
function Time:getBeginningOfServerToday()
if self:getServerTime() > self.todayTime + 86400 then
self.todayTime = self.todayTime + 86400
end
return self.todayTime
end
function Time:splitTime(time)
time = math.floor(time)
local reduceD = time % SECONDS_PRE_DAY
local day = math.floor(time / SECONDS_PRE_DAY)
local reduceH = reduceD % SECONDS_PRE_HOUR
local hour = math.floor(reduceD / SECONDS_PRE_HOUR)
local minute = math.floor(reduceH / SECONDS_PRE_MINUTE)
local second = reduceH % SECONDS_PRE_MINUTE
return day, hour, minute, second
end
-- 根据秒换算成向上取整hour的时间
function Time:getCeilHourTime(time)
local count = time // SECONDS_PRE_HOUR
if time % SECONDS_PRE_HOUR > 0 then
count = count + 1
end
return count
end
--每几秒 向上取整
function Time:getCeilPerSecend(time, per)
local count = time // per
if time % per > 0 then
count = count + 1
end
return count
end
-- 格式化文案 ----------------------------------------------------------------------------------------------------------------------------------------
-- 00:00:00
function Time:formatNumTime(time)
if time <= 0 then
return ZERO_TIME_STR
end
local reduceH = time % SECONDS_PRE_HOUR
local hour = math.floor(time / SECONDS_PRE_HOUR)
local minute = math.floor(reduceH / SECONDS_PRE_MINUTE)
local second = reduceH % SECONDS_PRE_MINUTE
return string.format("%.2d:%.2d:%.2d", hour, minute, second)
end
-- 00:00
function Time:formatNumTimeMS(time)
if time <= 0 then
return ZERO_TIME_STR_2
end
local minute = math.floor(time / SECONDS_PRE_MINUTE)
local second = time % SECONDS_PRE_MINUTE
return string.format("%.2d:%.2d", minute, second)
end
-- 大于1天显示X天X时 globalkey:ACTIVITY_TIME_STR_DH 小于1天显示X时X分 globalkey:ACTIVITY_TIME_STR_HM 小于1小时显示X分X秒 globalkey:ACTIVITY_TIME_STR_MS
function Time:formatNumTimeStr(time)
if time <= 0 then
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_MS, 0, 0)
end
local day, hour, minute, second = Time:splitTime(time)
if time >= SECONDS_PRE_DAY then -- 大于1天显示X天X时
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_DH, day, hour)
else
if time >= SECONDS_PRE_HOUR then -- 小于1天显示X时X分
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_HM, hour, minute)
else --小于1小时显示X分X秒
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_MS, minute, second)
end
end
end
-- 大于1小时显示X时前 globalkey:TIME_BEFORE_STR_H 小于1小时显示X分钟前 globalkey:TIME_BEFORE_STR_M 小于1分钟显示1分钟前
function Time:formatBeforeTimeStr(time)
local passTime = Time:getServerTime() - time
if passTime <= 0 then
return GConst.EMPTY_STRING
end
local hour = math.floor(passTime // SECONDS_PRE_HOUR)
if hour >= 1 then -- 大于1小时显示X时前
return I18N:getGlobalText(I18N.GlobalConst.TIME_BEFORE_STR_H, hour)
else
if passTime < SECONDS_PRE_MINUTE then
passTime = SECONDS_PRE_MINUTE
end
local min = math.floor(passTime // SECONDS_PRE_MINUTE)
return I18N:getGlobalText(I18N.GlobalConst.TIME_BEFORE_STR_M, min)
end
end
-- 格式化y/m/d时间返回os.data(finalTime)
function Time:formatTimeYMD(time)
time = time or self:getServerTime()
local date = self:getTimeFormat(time)
return date.year .. "/" .. date.month .. "/" .. date.day
end
-- 格式化y/m/d/h/m/s时间返回os.data(finalTime)
function Time:formatTimeYMDHMS(time)
time = time or Time:getServerTime()
local date = self:getTimeFormat(time)
return date.year .. "/" .. date.month .. "/" .. date.day .. " " .. date.hour .. ":" .. date.min .. ":" .. date.sec
end
-- 格式化y-m-d h:m:s时间返回os.data(finalTime)
function Time:formatTimeYMDHMS2(time)
time = time or Time:getServerTime()
local date = self:getTimeFormat(time)
return date.year .. "-" .. date.month .. "-" .. date.day .. " " .. date.hour .. ":" .. date.min .. ":" .. date.sec
end
-- 日相关时间接口 ------------------------------------------------------------------------------------------------------------------------
-- time日开始时的时间戳
function Time:getDayBeginTimeStamp(time)
time = time or self:getServerTime()
local now = self:getTimeFormatUTC(time)
local beginDay = os.time { year = now.year, month = now.month, day = now.day, hour = 0 }
return math.floor(beginDay - self:getTimeZoneOffset() * SECONDS_PRE_HOUR)
end
-- time日结束时的时间戳
function Time:getDayOverTimeStamp(time)
time = time or self:getServerTime()
local dateTable = self:getTimeFormatUTC(time)
local nextDay = os.time { year = dateTable.year, month = dateTable.month, day = dateTable.day + 1, hour = 0, min = 0, sec = 0 }
return math.floor(nextDay - self:getTimeZoneOffset() * SECONDS_PRE_HOUR)
end
-- 获取今日剩余时间
function Time:getTodaySurplusTime()
local result = self:getDayOverTimeStamp() - self:getServerTime()
if result < 0 then
result = 0
end
return result
end
-- 判断时间是否是大于等于今天
function Time:getTimeIsToday(time)
local todayBegin = self:getDayBeginTimeStamp()
return time >= todayBegin
end
-- 获取今天距目标日期的天数
function Time:getDistanceDays(time)
local nowNum = self:getDayBeginTimeStamp(self:getServerTime())
local targetNum = self:getDayBeginTimeStamp(time)
return (nowNum - targetNum) / 24 / 60 / 60
end
-- 周相关时间接口 ------------------------------------------------------------------------------------------------------------------------
-- time周开始时的时间戳
function Time:getWeekBeginTimeStamp(time)
time = time or self:getServerTime()
local remainDay = -self:getDayofWeek(time)
return math.floor(self:getDayOverTimeStamp(time) + remainDay * SECONDS_PRE_DAY)
end
-- time周结束时的时间戳
function Time:getWeekOverTimeStamp(time)
time = time or self:getServerTime()
local remainDay = 7 - self:getDayofWeek(time)
return math.floor(self:getDayOverTimeStamp(time) + remainDay * SECONDS_PRE_DAY)
end
-- 获取本周剩余时间
function Time:getWeekSurplusTime()
local result = self:getWeekOverTimeStamp() - self:getServerTime()
if result < 0 then
result = 0
end
return result
end
-- time时间在周第几天
function Time:getDayofWeek(time)
local curTime = time or self:getServerTime()
local day = tonumber(os.date("!%w", curTime))
day = day == 0 and 7 or day
return day
end
-- 月相关时间接口 ------------------------------------------------------------------------------------------------------------------------
-- time月开始的时间戳
function Time:getMonthBeginTimeStamp(time)
time = time or self:getServerTime()
local day = self:getDayofMonth(time) - 1
return math.floor(self:getDayBeginTimeStamp(time) - day * SECONDS_PRE_DAY)
end
-- time月结束的时间戳
function Time:getMonthOverTimeStamp(time)
time = time or self:getServerTime()
local now = self:getTimeFormatUTC(time)
now.month = now.month + 1
if now.month > 12 then
now.year = now.year + now.month // 12
now.month = now.month % 12
end
local remainDay = os.date("%d", os.time({ year = now.year, month = now.month, day = 0 })) - now.day
return math.floor(self:getDayOverTimeStamp(time) + remainDay * SECONDS_PRE_DAY)
end
-- time时间在月第几天
function Time:getDayofMonth(time)
time = time or self:getServerTime()
local now = self:getTimeFormatUTC(time)
return now.day
end
-- 其他接口 ------------------------------------------------------------------------------------------------------------------------
function Time:getXDaySecond(day)
return day * SECONDS_PRE_DAY
end
function Time:getAWeekSecond()
return self:getXDaySecond(DAY_PRE_WEEK)
end
--以秒为单位 计算时间差 返回 是否达到时间剩余时间00:00:00
function Time:checkTimeByMinutes(lastTriggerTime, minutes)
-- 计算从上次触发到现在经过的秒数
local currentTime = Time:getServerTime()
local elapsedSeconds = currentTime - lastTriggerTime
Logger.logHighlight(elapsedSeconds)
local freeSeconds = minutes * 60
-- 计算是否达到时间
if elapsedSeconds >= freeSeconds then
Logger.logHighlight(freeSeconds)
return true, nil
else
-- 计算剩余的秒数
local remainingSeconds = freeSeconds - elapsedSeconds
Logger.logHighlight(remainingSeconds)
-- 计算小时数
local hours = math.floor(remainingSeconds / 3600)
-- 计算剩余的分钟数
local minutes = math.floor((remainingSeconds % 3600) / 60)
-- 计算剩余的秒数
local seconds = remainingSeconds % 60
-- 格式化时间为 00:00:00 的形式
local formattedTime = string.format("%02d:%02d:%02d", hours, minutes, seconds)
return false, formattedTime
end
end
return Time