timeUtil.lua 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. local skynet = require "skynet"
  2. local moduleData = require("data.module")
  3. local root = {
  4. SEC_PER_HOUR = 3600,
  5. SEC_PER_DAY = 86400,
  6. SEC_PER_WEEK = 7 * 86400,
  7. REFRESH_HOUR = 5
  8. }
  9. -- 获取当前时间 单位秒
  10. function root.currentTime()
  11. return math.floor(skynet.time())
  12. end
  13. -- 获取玩家当前时间
  14. function root.now(uid)
  15. local currTime = skynet_time()
  16. if not IS_TEST then
  17. return currTime
  18. end
  19. local deltaTime = moduleData:hget_int(uid, "user", "time:sys")
  20. if not is_empty(deltaTime) then
  21. return currTime + deltaTime
  22. end
  23. return currTime
  24. end
  25. function root.toString(t)
  26. return os.date("%Y-%m-%d %H:%M:%S", t)
  27. end
  28. function root.toDate(t)
  29. return os.date("%Y-%m-%d", t or root.currentTime())
  30. end
  31. function root.toTab(t)
  32. return os.date("*t", t)
  33. end
  34. function root.toInt(tab)
  35. return os.time(tab)
  36. end
  37. function root.getYday(t)
  38. return os.date("%j", t)
  39. end
  40. -- 获取时间的0点时间戳
  41. function root.getCday(ctime)
  42. local a = root.toTab(ctime)
  43. a.hour, a.min, a.sec = 0, 0, 0
  44. return root.toInt(a)
  45. end
  46. -- 将时间格式化秒 %Y-%m-%d %H:%M:%S
  47. function root.getSecond(t)
  48. local function split(str, pat)
  49. local t = {}
  50. local fpat = "(.-)" .. pat
  51. local last_end = 1
  52. local s, e, cap = str:find(fpat, 1)
  53. while s do
  54. if s ~= 1 or cap ~= "" then
  55. table.insert(t, cap)
  56. end
  57. last_end = e + 1
  58. s, e, cap = str:find(fpat, last_end)
  59. end
  60. if last_end <= #str then
  61. cap = str:sub(last_end)
  62. table.insert(t, cap)
  63. end
  64. return t
  65. end
  66. local a = split(t, " ")
  67. local b = split(a[1], "-")
  68. local c = split(a[2], ":")
  69. return root.toInt({year = b[1], month = b[2], day = b[3], hour = c[1], min = c[2], sec = c[3]})
  70. end
  71. function root.getDayCount(year, month)
  72. local year = tonumber(year)
  73. local month = tonumber(month)
  74. if not year or not month then
  75. return 0
  76. end
  77. if month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12 then
  78. return 31
  79. end
  80. if month == 2 then
  81. if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
  82. return 29
  83. else
  84. return 28
  85. end
  86. end
  87. return 30
  88. end
  89. function root.getTime(year, month, day, hour, min, sec)
  90. local timeStruct = {}
  91. timeStruct.sec = tonumber(sec) or 0
  92. timeStruct.min = tonumber(min) or 0
  93. timeStruct.hour = tonumber(hour) or 0
  94. timeStruct.day = tonumber(day) or 0
  95. timeStruct.month = tonumber(month) or 0
  96. timeStruct.year = tonumber(year) or 0
  97. return root.toInt(timeStruct)
  98. end
  99. -- 能否日刷新
  100. function root.dailyRefresh(atime, btime, hour, min, sec)
  101. local atime = tonumber(atime) or 0
  102. local btime = tonumber(btime) or root.currentTime()
  103. local hour, min, sec = tonumber(hour) or 0, tonumber(min) or 0, tonumber(sec) or 0
  104. local aTimeTab, bTimeTab = root.toTab(atime), root.toTab(btime)
  105. bTimeTab.hour, bTimeTab.min, bTimeTab.sec = hour, min, sec
  106. aTimeTab.hour, aTimeTab.min, aTimeTab.sec = hour, min, sec
  107. -- 超过1天
  108. if btime - atime >= 24 * 60 * 60 then
  109. return true
  110. end
  111. -- 1天之内
  112. if btime >= root.toInt(aTimeTab) and root.toInt(aTimeTab) >= atime then
  113. return true
  114. end
  115. if btime >= root.toInt(bTimeTab) and root.toInt(bTimeTab) >= atime then
  116. return true
  117. end
  118. return false
  119. end
  120. -- 能否周刷新 [wday=2 是周一]
  121. function root.WeekRefresh(atime, btime, wday, hour, min, sec)
  122. atime = tonumber(atime) or 0
  123. btime = tonumber(btime) or root.currentTime()
  124. wday, hour, min, sec = tonumber(wday) or 2, tonumber(hour) or 0, tonumber(min) or 0, tonumber(sec) or 0
  125. local aTimeTab, bTimeTab = root.toTab(atime), root.toTab(btime)
  126. bTimeTab.day = bTimeTab.day + (wday - bTimeTab.wday)
  127. aTimeTab.day = aTimeTab.day + (wday - aTimeTab.wday)
  128. bTimeTab.hour, bTimeTab.min, bTimeTab.sec = hour, min, sec
  129. aTimeTab.hour, aTimeTab.min, aTimeTab.sec = hour, min, sec
  130. -- 超过七天
  131. if btime - atime >= 7 * 24 * 60 * 60 then
  132. return true
  133. end
  134. -- 七天之内
  135. if btime >= root.toInt(aTimeTab) and root.toInt(aTimeTab) >= atime then
  136. return true
  137. end
  138. if btime >= root.toInt(bTimeTab) and root.toInt(bTimeTab) >= atime then
  139. return true
  140. end
  141. return false
  142. end
  143. -- 能否月刷新
  144. function root.can_month_refresh(atime, btime, in_day, hour, min, sec)
  145. local atime = tonumber(atime) or 0
  146. local btime = tonumber(btime) or root.currentTime()
  147. local bTimeTab, aTimeTab = root.toTab(btime), root.toTab(atime)
  148. local day, hour, min, sec = tonumber(in_day) or 1, tonumber(hour) or 0, tonumber(min) or 0, tonumber(sec) or 0
  149. aTimeTab.day, aTimeTab.hour, aTimeTab.min, aTimeTab.sec = day, hour, min, sec
  150. bTimeTab.day, bTimeTab.hour, bTimeTab.min, bTimeTab.sec = day, hour, min, sec
  151. -- 超过一月
  152. local month = (bTimeTab.year - aTimeTab.year) * 12
  153. if bTimeTab.month + month > aTimeTab.month + 1 then
  154. return true
  155. end
  156. -- 一月之内
  157. if btime >= root.toInt(aTimeTab) and root.toInt(aTimeTab) >= atime then
  158. return true
  159. end
  160. if btime >= root.toInt(bTimeTab) and root.toInt(bTimeTab) >= atime then
  161. return true
  162. end
  163. return false
  164. end
  165. -- 两个时间相距天数
  166. function root.getDisDays(t1, t2)
  167. if t1 == nil or t2 == nil then
  168. return 0
  169. end
  170. local d1 = root.getYday(t1)
  171. local d2 = root.getYday(t2)
  172. return math.abs(d1 - d2)
  173. end
  174. function root.is_same_day(t1, t2)
  175. if t1 == nil or t2 == nil then
  176. return false
  177. end
  178. local d1 = root.getYday(t1)
  179. local d2 = root.getYday(t2)
  180. if d1 == d2 then
  181. return true
  182. end
  183. return false
  184. end
  185. -- 是否同一天(凌晨5点)
  186. function root.is_same_c5_day(t1, t2)
  187. if t1 == nil or t2 == nil then
  188. return false
  189. end
  190. local d1 = root.getYday(t1 - 5 * 3600)
  191. local d2 = root.getYday(t2 - 5 * 3600)
  192. if d1 == d2 then
  193. return true
  194. end
  195. return false
  196. end
  197. -- 获取当前天数(自1970年)
  198. function root.getDaysOfTimestampExt(timestamp, diffTime)
  199. timestamp = (timestamp or root.currentTime()) - (diffTime or 0)
  200. return math.floor((timestamp + (8 * 3600)) / (3600 * 24))
  201. end
  202. -- 获取获取相差的天数
  203. function root.getDisDaysC5(t1, t2)
  204. if t1 == nil or t2 == nil then
  205. return 0
  206. end
  207. local d1 = root.getDaysOfTimestampExt(t1, 5 * 3600)
  208. local d2 = root.getDaysOfTimestampExt(t2, 5 * 3600)
  209. return math.abs(d1 - d2)
  210. end
  211. -- 获取获取相差的天数
  212. function root.getDisDaysExt(t1, t2)
  213. if t1 == nil or t2 == nil then
  214. return 0
  215. end
  216. local d1 = root.getDaysOfTimestampExt(t1)
  217. local d2 = root.getDaysOfTimestampExt(t2)
  218. return math.abs(d1 - d2)
  219. end
  220. -- 获取下一个凌晨5点时间戳
  221. function root.get_next_c5_time(currTime)
  222. currTime = currTime or skynet_time()
  223. local startTime = root.getDayStartTime(currTime) + 5 * 3600
  224. if currTime >= startTime then
  225. return startTime + 24 * 3600
  226. end
  227. return startTime
  228. end
  229. -- 获取下周一开始时间 5点
  230. function root.c5_get_next_week_start_time(currTime)
  231. local date = os.date("*t", currTime)
  232. -- log.info("获取下周一5点时间 date[%s]", tostring(date))
  233. if date.wday == 1 and date.hour < 5 then
  234. return root.getTime(date.year, date.month, date.day, 5, 0, 0)
  235. end
  236. local diffDays
  237. local wday = date.wday - 1
  238. if wday == 0 then
  239. wday = 7
  240. end
  241. diffDays = 8 - wday
  242. -- log.info("diffDays = %s", diffDays)
  243. return root.getDayStartTime(currTime, diffDays) + 5 * 3600
  244. end
  245. -- 获取下个月1号开始时间 5点
  246. function root.c5_get_next_month_start_time(currTime)
  247. local date = os.date("*t", currTime)
  248. -- log.info("获取下周一5点时间 date[%s]", tostring(date))
  249. if date.day == 1 and date.hour < 5 then
  250. return root.getTime(date.year, date.month, date.day, 5, 0, 0)
  251. end
  252. date.month = date.month + 1
  253. return root.getTime(date.year, date.month, date.day, 5, 0, 0)
  254. end
  255. -- 两个时间间隔(凌晨5点)
  256. function root.get_c5_dis_days(t1, t2)
  257. if t1 == nil or t2 == nil then
  258. return 0
  259. end
  260. local d1 = root.getYday(t1 - 5 * 3600)
  261. local d2 = root.getYday(t2 - 5 * 3600)
  262. return math.abs(d1 - d2)
  263. end
  264. function root.isSameWeek(t1, t2)
  265. local dateA = os.date("*t", t1)
  266. local dateB = os.date("*t", t2)
  267. local diff = math.abs(dateA.yday - dateB.yday)
  268. if diff == 0 then
  269. return true
  270. end
  271. local beforeDt = 0
  272. if dateA.yday < dateB.yday then
  273. beforeDt = dateA
  274. else
  275. beforeDt = dateB
  276. end
  277. if diff > 7 then
  278. return false
  279. end
  280. local wday = beforeDt.wday - 1
  281. if wday == 0 then
  282. wday = 7
  283. end
  284. if wday + diff > 7 then
  285. return false
  286. end
  287. return true
  288. end
  289. function root.isSameMonth(t1, t2)
  290. if t1 == nil or t2 == nil then
  291. return false
  292. end
  293. local n1 = os.date("*t", t1)
  294. local n2 = os.date("*t", t2)
  295. if n1.year == n2.year and n1.month == n2.month then
  296. return true
  297. end
  298. return false
  299. end
  300. -- 获取当天结束时间
  301. function root.getDayEndTime(currTime, days)
  302. local daySec = 24 * 3600
  303. local addDay = days or 1
  304. local timeout = math.floor((currTime + 8 * 3600) / daySec) * daySec + daySec * addDay - 8 * 3600 - 1
  305. return timeout
  306. end
  307. -- 获取当天开始时间
  308. function root.getDayStartTime(currTime, days)
  309. local daySec = 24 * 3600
  310. local addDay = days or 0
  311. local timeout = math.floor((currTime + 8 * 3600) / daySec) * daySec + daySec * addDay - 8 * 3600
  312. return timeout
  313. end
  314. -- 获取当前周开始时间[周日开始]
  315. function root.getWeekStartTime(currTime)
  316. local t = root.toTab(currTime)
  317. local startTime = root.getDayStartTime(currTime)
  318. return startTime - (t.wday - 1) * root.SEC_PER_DAY
  319. end
  320. -- 获取当天周结束时间[周六结束]
  321. function root.getWeekEndTime(currTime)
  322. local startTime = root.getWeekStartTime(currTime)
  323. return startTime + root.SEC_PER_WEEK - 1
  324. end
  325. -- 获取当前周的指定时间的时间戳[从周日起]
  326. -- day周日为0,周六为6
  327. function root.getTimeByWeek(currTime, day, h, m, s)
  328. day = day or 0
  329. h = h or 0
  330. m = m or 0
  331. s = s or 0
  332. local startTime = root.getWeekStartTime(currTime)
  333. local addTime = day * root.SEC_PER_DAY + h * root.SEC_PER_HOUR + m * 60 + s
  334. return startTime + addTime
  335. end
  336. -- 获取现在时间是几星期几.day周日为0,周六为6
  337. function root.getWeekDay(currTime)
  338. local tab = os.date("*t", currTime or os.time())
  339. return tab.wday - 1
  340. end
  341. -- 获取当天0点时间戳
  342. function root.getUnixtimeToday(t1)
  343. local nt = os.date("*t", t1)
  344. return os.time({year = nt.year, month = nt.month, day = nt.day, hour = 0, min = 0, sec = 0})
  345. end
  346. -- 获取明天0点时间戳
  347. function root.getUnixtimeTomorrow(t1)
  348. return root.getUnixtimeToday(t1) + 86400
  349. end
  350. -- 明天零点倒计时
  351. function root.countdownToTomorrow(t1)
  352. return root.getUnixtimeTomorrow(t1) - (t1 or os.time())
  353. end
  354. -- 跨分钟数
  355. function root.get_across_minutes(startTime, endTime)
  356. if startTime == nil or endTime == nil then
  357. return 0
  358. end
  359. local s = math.floor(startTime / 60)
  360. local e = math.floor(endTime / 60)
  361. if endTime > e * 60 then
  362. e = e + 1
  363. end
  364. log.info(
  365. "get_across_minutes startTime[%s] s[%s] endTime[%s] e[%s]",
  366. tostring(startTime),
  367. tostring(s),
  368. tostring(endTime),
  369. tostring(e)
  370. )
  371. return math.abs(e - s)
  372. end
  373. -- 跨小时数(rate每多少整小时,可以是每整1小时,也可以是每整2小时)
  374. function root.get_across_hours(startTime, endTime, rate)
  375. if startTime == nil or endTime == nil then
  376. return 0
  377. end
  378. if not rate then
  379. rate = 3600
  380. end
  381. local s = math.floor(startTime / rate)
  382. local e = math.floor(endTime / rate)
  383. log.info(
  384. "get_across_hours startTime[%s] s[%s] endTime[%s] e[%s]",
  385. tostring(startTime),
  386. tostring(s),
  387. tostring(endTime),
  388. tostring(e)
  389. )
  390. return math.abs(e - s)
  391. end
  392. -- 跨天数
  393. function root.c5_get_cross_days(startTime, endTime)
  394. if startTime == nil or endTime == nil then
  395. return 0
  396. end
  397. local days = 0
  398. local nextTime = root.get_next_c5_time(startTime)
  399. while nextTime < endTime do
  400. days = days + 1
  401. nextTime = nextTime + 24 * 3600
  402. end
  403. return days
  404. end
  405. --#region ----------------------------------------- 时间的扩展:功能代码块
  406. -- 为什么重新实现?
  407. -- 部分功能实现得过于复杂,没必要过于遇合,需要考虑到lua的性能消耗.
  408. -- 获取当天0点时间戳
  409. function root.getTodayHourTimestamp(hour)
  410. local t_date = os.date("*t")
  411. return os.time(
  412. {
  413. year = t_date.year,
  414. month = t_date.month,
  415. day = t_date.day,
  416. hour = hour or root.REFRESH_HOUR,
  417. min = 0,
  418. sec = 0
  419. }
  420. )
  421. end
  422. -- 跨天数
  423. -- 获取某个时间戳跨越了多少天(5点为分界线)
  424. function root.getDaysOfTimestamp(timestamp)
  425. -- 错误的时间参数返回1天
  426. if not timestamp or timestamp == 0 then
  427. return 1
  428. end
  429. local dt = root.getTodayHourTimestamp()
  430. if timestamp > dt then
  431. -- 以一天来计算,可能
  432. -- return 888
  433. return math.ceil((timestamp - dt) / root.SEC_PER_DAY)
  434. else
  435. -- 逻辑刷新前面要加1.
  436. return math.ceil((dt - timestamp) / root.SEC_PER_DAY) + 1
  437. end
  438. end
  439. -- 是否已经跨天了
  440. function root.isOtherDay(uid, actData)
  441. -- 刷新时间
  442. local currTime = root.now(uid or 0)
  443. if actData.nextUT == nil or currTime >= actData.nextUT then
  444. actData.nextUT = root.get_next_c5_time(currTime)
  445. return true
  446. end
  447. return false
  448. end
  449. --#endregion
  450. return root