lua 日期时间处理工具类
羽扇纶巾,运筹帷幄,决胜于千里之外,谈笑间,樯橹灰飞烟灭。仰望苍穹,谁能如此自如。昔人如此光耀,却终究为工具人生,竞引后世猿们凭空吊牢骚。望道未见,自嗟叹之余,亦不觉已为工具人。
DateUtil = DateUtil or {}
----------------------------------------------------------------
-- Lua中 os.date() 的特殊标记及其含义
-- %y 两位数的年份。 例如(98),范围 [00~99]
-- %Y 完整的年份。例如(1998)
-- %m 月份数。 例如(09),范围 [01~12]
-- %d 一个月中的第几天。 例如(16),范围 [01~31]
-- %H 24小时制中的小时数。 例如(23),范围 [00~23]
-- %I 12小时制中的小时数。 例如(11),范围 [01~12]
-- %M 分钟数。 例如(49),范围 [00~59]
-- %S 秒数。 例如(10),范围 [00~59]
-- %p “上午(am)” 或 “下午(pm)“
-- %j 一年中的第几天。 例如(259),范围 [001~366]
-- %w 一星期中的第几天。 例如(3),范围 [0~6]
-- %a 一星期中天数的简写。 例如(Wed)
-- %A 一星期中天数的全称。 例如(Wednesday)
-- %b 月份的简写。 例如(Sep)
-- %B 月份的全称。 例如(September)
-- %c 日期和时间。 例如(09/16/98 23:48:10)
-- %x 日期。 例如(09/16/98)
-- %X 时间。 例如(23:48:10)
----------------------------------------------------------------
--返回当前的时间戳,单位为秒
function DateUtil.getNowTime()
return os.time()
end
-- 返回时间字符串,format是格式,如"%Y-%m-%d %H:%M:%S",time是时间戳数值
function DateUtil.formatDate(format, time)
return os.date(format, time)
end
--把时间解析成表,time是是时间戳数值
--解析后格式为: { year=x, month=x, day=x, hour=x, min=x, sec=x,isdst=false, wday=x, yday=x }
function DateUtil.parseTimeToTable(time)
local tab = os.date("*t", time)
return tab
end
function DateUtil.getSystemDateString()
return os.date("%Y-%m-%d %H:%M:%S", os.time())
end
--返回日期格式的字符串
function DateUtil.getDateFomatString(time)
return os.date("%Y-%m-%d %H:%M:%S", time)
end
--返回简单日期格式的字符串
function DateUtil.getDateSimpleString(time)
return os.date("%Y-%m-%d", time)
end
--返回时钟格式的字符串
function DateUtil.getTimeFomatString(time)
return os.date("%H:%M:%S", time)
end
--日期转换为时间戳(整数类型)
function DateUtil.getDateValue(year, month, day)
return os.time({ year=year, month=month, day=day, hour=0, min=0, sec=0 })
end
--日期和时间转换为时间戳(整数类型)
function DateUtil.getDateTimeValue(year, month, day, hour, min, sec)
return os.time({ year=year, month=month, day=day, hour=hour, min=min, sec=sec})
end
--日期转换为时间戳(tab是表格式) 如{year=year, month=month, day=day, hour=hour, min=min, sec=sec}
function DateUtil.getDateValueByTab(tabInfo)
return os.time(tabInfo)
end
--年份
function DateUtil.getYear(time)
local ret = 0
if time then
ret = tonumber(os.date("%Y", time)) or 0
end
return ret
end
--月份
function DateUtil.getMonth(time)
local ret = 0
if time then
ret = tonumber(os.date("%m", time)) or 0
end
return ret
end
--日子
function DateUtil.getDay(time)
local ret = 0
if time then
ret = tonumber(os.date("%d", time)) or 0
end
return ret
end
--时
function DateUtil.getHour(time)
local ret = 0
if time then
ret = tonumber(os.date("%H", time)) or 0
end
return ret
end
--分
function DateUtil.getMin(time)
local ret = 0
if time then
ret = tonumber(os.date("%M", time)) or 0
end
return ret
end
--秒
function DateUtil.getSec(time)
local ret = 0
if time then
ret = tonumber(os.date("%S", time)) or 0
end
return ret
end
--获取周几, 顺序是(周日,周一...周六), 分别对应数值1-7
function DateUtil.getWeekDay(time)
local ret = 0
if time then
local info = os.date("*t", time)
if info and info.wday then
ret = info.wday
end
end
return ret
end
-- 距离系统时间的间隔秒数
function DateUtil.getDiffTime(time)
local ret = 0
if time then
local now = os.time()
ret = os.difftime(time, now)
end
return ret
end
-- 根据时间来计算日数差值(不足一天也计算为一天)
-- 例如:今天时间是23:00, 明天的时间是1:00, 时间不足24小时,但日数的差值也为1
function DateUtil.getDateNum(timeNow, timeNext)
local ret = 0
if timeNow and timeNext then
local now = os.date("*t", timeNow)
local next = os.date("*t", timeNext)
if now and next then
local num1 = os.time({ year = now.year, month=now.month, day=now.day })
local num2 = os.time({ year = next.year, month=next.month, day=next.day })
if num1 and num2 then
ret = math.abs(num1 - num2) / (3600*24)
end
end
end
return ret
end
-- 两个日期字符的日数差值
function DateUtil.getStringDateNum(strFirst, strSecond)
if strFirst and strSecond then
local time1 = DateUtil.parseSimpleDate(strFirst)
local time2 = DateUtil.parseSimpleDate(strSecond)
if time1 > 0 and time2 > 0 then
return DateUtil.getDateNum(time1, time2)
end
end
return 0
end
-- 判断两个日期是否是同一天,只对比日期
-- 参数是时间戳的整型数值
function DateUtil.isSameDay(first, second)
if first and second then
local tab1 = os.date("*t", first)
local tab2 = os.date("*t", second)
if tab1 and tab2 then
if tab1.year == tab2.year and tab1.month == tab2.month and tab1.day == tab2.day then
return true
end
end
end
return false
end
----------------------------------------------------------------
-- 对比两个日期, 参数为时间戳的整型数值,只对比日期
-- =2: 日期相同
-- =1: second > first
-- =-1: second < first
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareDay(first, second)
if first and second then
local tab1 = os.date("*t", first)
local tab2 = os.date("*t", second)
if tab1 and tab2 then
--相等
if tab1.year == tab2.year and tab1.month == tab2.month and tab1.day == tab2.day then
return 2
end
--second大于first的处理
if tab2.year > tab1.year then
return 1
end
if tab2.year == tab1.year and tab2.month > tab1.month then
return 1
end
if tab2.year == tab1.year and tab2.month == tab1.month and tab2.day > tab1.day then
return 1
end
return -1
end
end
return 0
end
----------------------------------------------------------------
-- 对比两个日期字符串,只对比日期,参数是字符串
-- 日期字符串的格式需符合以下三种: yyyyMMdd 或 yyyy-MM-dd 或 yyyy/MM/dd
-- =2: 日期相同
-- =1: strDate2 > strDate1
-- =-1: strDate2 < strDate1
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareDayString(strDate1, strDate2)
local ret = 0
if strDate1 and strDate2 then
local time1 = DateUtil.parseSimpleDate(strDate1)
local time2 = DateUtil.parseSimpleDate(strDate2)
if time1 > 0 and time2 > 0 then
ret = DateUtil.compareDay(time1, time2)
end
end
return ret
end
----------------------------------------------------------------
-- 对比日期字符串, 与当前系统时间比较,只对比日期
-- 日期字符串格式需要严格符合以下三种: yyyyMMdd 或 yyyy-MM-dd 或 yyyy/MM/dd
-- =2: 日期相同
-- =1: strDate > system
-- =-1: strDate < system
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareDayWithSystem(strDate)
local ret = 0
if strDate then
local time = DateUtil.parseSimpleDate(strDate)
local now = os.time()
if time > 0 then
ret = DateUtil.compareDay(now, time)
end
end
return ret
end
----------------------------------------------------------------
-- 判断时钟数值的大小,单位为秒
-- =2: 时间相同
-- =1: second > first
-- =-1: second < first
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareClockTimeValue(first, second)
if first and second then
if first < second then
return 1
elseif first == second then
return 2
else
return -1
end
end
return 0
end
----------------------------------------------------------------
-- 判断两个时钟字符串的大小, 时钟格式需为: 00:00:00
-- =2: 时间相同
-- =1: second > first
-- =-1: second < first
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareClockTimeString(strFirst, strSecond)
local ret = 0
if strFirst and strSecond then
local first = DateUtil.parseSimpleClockTime(strFirst)
local second = DateUtil.parseSimpleClockTime(strSecond)
if first > 0 and second > 0 then
ret = DateUtil.compareClockTimeValue(first, second)
end
end
return ret
end
----------------------------------------------------------------
-- 判断时钟字符串的大小,与系统时间对比, 格式为 00:00:00
-- =2: 时间相同
-- =1: strTime > now
-- =-1: strTime < now
-- =0: 无效值
----------------------------------------------------------------
function DateUtil.compareClockTimeWithSystem(strTime)
local ret = 0
if strTime then
local now = os.time()
local time = DateUtil.parseSimpleClockTime(strTime)
if time > 0 then
ret = DateUtil.compareClockTimeValue(now, time)
end
end
return ret
end
-- 昨天的起始时间戳,time是时间整型数值
function DateUtil.getYesterDay(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num and num >= 3600 * 24 then
ret = num - 3600 * 24
end
end
end
return ret
end
-- 明天的起始时间戳,time是时间整型数值
function DateUtil.getTomorrowDate(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num then
ret = num + 3600 * 24
end
end
end
return ret
end
--N天前的一天,dayNum为多少天,time指从指定整型时间开始
function DateUtil.getBeforeDateByNum(time, dayNum)
local ret = 0
if time and dayNum then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num and num >= dayNum*3600*24 then
ret = num - dayNum*3600*24
end
end
end
return ret
end
--N天后的一天, dayNum为多少天,time指从指定整型时间开始
function DateUtil.getAfterDateByNum(time, dayNum)
local ret = 0
if time and dayNum then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num then
ret = num + dayNum*3600*24
end
end
end
return ret
end
-- 获取两个日期之间的全部天数,返回整型时间列表
function DateUtil.getDateList(startDate, lastDate)
local list = {}
local oneDate = 3600 * 24
if startDate and lastDate then
local tab1 = os.date("*t", startDate)
local tab2 = os.date("*t", lastDate)
if tab1 and tab2 then
local start = os.time({year = tab1.year, month=tab1.month, day=tab1.day, hour=0, min=0, sec=0})
local last = os.time({year = tab2.year, month=tab2.month, day=tab2.day, hour=0, min=0, sec=0})
if start and last then
while start + oneDate < last do
start = start + oneDate
table.insert(list, start)
end
end
end
end
return list
end
-- 获取从昨天开始的N个日期列表
function DateUtil.getDayListFromYestoday(time, dayNum)
local list = {}
if time and dayNum then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num then
for i=1, dayNum do
if num >= 3600*24 then
num = num - 3600*24
else
break
end
table.insert(list, num)
end
end
end
end
return list
end
-- 获取从明天开始的N个日期列表
function DateUtil.getDayListFromTomorrow(time, dayNum)
local list = {}
if time and dayNum then
local now = os.date("*t", time)
if now then
local num = os.time({year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if num then
for i=1, dayNum do
num = num + 3600*24
table.insert(list, num)
end
end
end
end
return list
end
-- 获取当月的天数
function DateUtil.getMonthDayCount(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local year = now.year
local month = now.month
if month == 12 then
month = 1
year = year + 1
else
month = month + 1
end
local num = os.time({ year = year, month=month, day=1, hour=0, min=0, sec=0})
if num and num > 3600*24 then
num = num - 3600*24
ret = os.date("%d", num)
end
end
end
return ret
end
-- 本月第一天的时间戳
function DateUtil.getStartDateThisMonth(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
ret = os.time({ year = now.year, month=now.month, day=1, hour=0, min=0, sec=0}) or 0
end
end
return ret
end
-- 下月第一天的时间戳
function DateUtil.getStartDateNextMonth(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local month = now.month
local year = now.year
if month == 12 then
month = 1
year = year + 1
else
month = month + 1
end
ret = os.time({ year = year, month=month, day=1, hour=0, min=0, sec=0}) or 0
end
end
return ret
end
-- 上月第一天的时间戳
function DateUtil.getStartDatePrevMonth(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local month = now.month
local year = now.year
if month == 1 then
month = 12
year = year - 1
else
month = month - 1
end
ret = os.time({ year = year, month=month, day=1, hour=0, min=0, sec=0}) or 0
end
end
return ret
end
-- 计算一年有多少天
-- 年份能被4整除的是闰年,一年有366天,但尾数是成百的要被400整除的是闰年
-- 2100年不能被400整除,不是闰年,2000年被400整除,是闰年
function DateUtil.getYearDays(time)
local ret = 365
if time then
local now = os.date("*t", time)
if now then
local year = now.year
local is4 = (year % 4 ) == 0
local is100 = (year % 100) == 0
if is100 then
local is400 = (year % 400) == 0
if is4 and is400 then
return 366
end
else
if is4 then
return 366
end
end
end
end
return ret
end
--当天在一年中的第几天
function DateUtil.getDaysInYear(time)
local ret = 0
if time then
local info = os.date("*t", time)
if info then
--获取当年1月份第一天的时间,时间差除以一天的时间,并向上取整
local start = os.time({ year=info.year, month=1, day=1, hour=0, min=0, sec=0})
if start then
ret = math.ceil((time - start) / (3600 * 24))
end
end
end
return ret
end
--今年还剩多少天
function DateUtil.getRestDayOfYear(time)
local ret = 0
if time then
local daysYear = DateUtil.getYearDays(time)
local curDay = DateUtil.getDaysInYear(time)
ret = daysYear - curDay
end
return ret
end
--当前季度的开始的时间戳
function DateUtil.getFirstDayOfSeason(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local month = now.month
local startMonth = 0
if month <= 3 then
startMonth = 1
elseif month >= 4 and month <= 6 then
startMonth = 4
elseif month >= 7 and month <= 9 then
startMonth = 7
elseif month >= 10 and month <= 12 then
startMonth = 10
end
ret = os.time({ year = now.year, month=startMonth, day=1, hour=0, min=0, sec=0}) or 0
end
end
return ret
end
--当前季度的结束的时间戳
function DateUtil.getLastDayOfSeason(time)
local ret = 0
if time then
local now = os.date("*t", time)
if now then
local month = now.month
local year = now.year
local lastMonth = 0
if month <= 3 then
lastMonth = 4
elseif month >= 4 and month <= 6 then
lastMonth = 7
elseif month >= 7 and month <= 9 then
lastMonth = 10
elseif month >= 10 and month <= 12 then
lastMonth = 1
year = year + 1
end
ret = os.time({ year = year, month=lastMonth, day=1, hour=0, min=0, sec=0})
if ret and ret > 0 then
--减小一秒,即前一天的结束时间
ret = ret - 1
end
end
end
return ret
end
--获取一周的的日期列表,周一开始,周日结束
function DateUtil.getWholeWeekDays(time)
local list = {}
if time then
local now = os.date("*t", time)
if now then
local weekNum = DateUtil.getWeekDay(time) --当天是周几
local wTime = os.time({ year = now.year, month=now.month, day=now.day, hour=0, min=0, sec=0})
if wTime then
--计算周一的起始时间,由于周日的weekNum=1
if weekNum == 1 then
--当前是周日, 减去6天的日期
wTime = wTime - 3600*24*6
else
wTime = wTime - 3600*24*(weekNum-1) + 3600*24
end
for i=1, 7 do
if i > 1 then
wTime = wTime + 3600*24
end
table.insert(list, wTime)
end
end
end
end
return list
end
-- 判断日期是否合法日期字符串
-- 只对比日期格式,不要加时钟, 格式只支持: yyyyMMdd 或 yyyy-MM-dd 或 yyyy/MM/dd
-- 返回fale是不符合时间格式,否则返回true
function DateUtil.isValidDate(strDate)
local ret = false
local strYear, strMonth, strDay = nil, nil, nil
if strDate then
if #strDate == 8 or #strDate == 10 then
local digitCnt, hengGang, xieGang = 0, 0, 0
for i=1, #strDate do
local val = string.byte(strDate, i)
if val >= 0x30 and val <= 0x39 then
digitCnt = digitCnt + 1
elseif val == 0x2D then --符号"-"
hengGang = hengGang + 1
elseif val == 0x2F then --符号"/"
xieGang = xieGang + 1
end
end
if #strDate == 8 then
if digitCnt == 8 then
strYear = string.sub(strDate, 1, 4)
strMonth = string.sub(strDate, 5, 6)
strDay = string.sub(strDate, 7, 8)
end
elseif #strDate == 10 then
if (digitCnt == 8) and (hengGang == 2 or xieGang == 2) then
strYear = string.sub(strDate, 1, 4)
strMonth = string.sub(strDate, 6, 7)
strDay = string.sub(strDate, 9, 10)
end
end
end
if strYear and strMonth and strDay then
local year = tonumber(strYear)
if not year then
print("year err", strYear) --年份不能解析
return ret
end
if (year < 1900) or (year > 2200) then
print("year out of range =", strYear) --年份不在范围
return ret
end
local month = tonumber(strMonth)
if (not month) or (month <= 0) or (month > 12) then
print("month err =", strMonth)
return ret
end
local day = tonumber(strDay)
if (not day) or (day <= 0) or (day > 31) then
print("day err =", strDay)
return ret
end
return true
end
end
return ret
end
--时钟数据的格式是否有效 00:00, 10:10:00
function DateUtil.isValidClockTime(strTime)
if DateUtil.parseSimpleClockTime(strTime) > 0 then
return true
end
return false
end
-- 解析日期格式,只解析简单格式的日期
-- 日期字符串格式需要严格符合以下三种: yyyyMMdd 或 yyyy-MM-dd 或 yyyy/MM/dd
-- 返回0是不符合时间格式,返回时间数值则是当前时间数值
function DateUtil.parseSimpleDate(strDate)
local ret = 0
local strYear, strMonth, strDay = nil, nil, nil
if strDate then
if #strDate == 8 or #strDate == 10 then
local digitCnt, hg, xg = 0, 0, 0
for i=1, #strDate do
local val = string.byte(strDate, i)
if val >= 0x30 and val <= 0x39 then
digitCnt = digitCnt + 1
elseif val == 0x2D then --"-"
hg = hg + 1
elseif val == 0x2F then --"/"
xg = xg + 1
end
end
if #strDate == 8 then
if digitCnt == 8 then
strYear = string.sub(strDate, 1, 4)
strMonth = string.sub(strDate, 5, 6)
strDay = string.sub(strDate, 7, 8)
end
elseif #strDate == 10 then
if (digitCnt == 8) and (hg == 2 or xg == 2) then
strYear = string.sub(strDate, 1, 4)
strMonth = string.sub(strDate, 6, 7)
strDay = string.sub(strDate, 9, 10)
end
end
end
if strYear and strMonth and strDay then
local year = tonumber(strYear)
if not year then
print("year err", strYear) --年份不能解析
return ret
end
if (year < 1900) or (year > 2200) then
print("year out of range =", strYear) --年份不在范围
return ret
end
local month = tonumber(strMonth)
if (not month) or (month <= 0) or (month > 12) then
print("month err =", strMonth)
return ret
end
local day = tonumber(strDay)
if (not day) or (day <= 0) or (day > 31) then
print("day err =", strDay)
return ret
end
ret = os.time({year=year, month=month, day=day, hour=0, min=0, sec=0}) or 0
return ret
end
end
return ret
end
----------------------------------------------------------------
-- 解析日期和时间格式的字符串,返回时间戳数值 (满足不同的时间格式,功能强大)
-- 以下的日期格式都能解析:
-- 2021-06-05 18:12:05 --(符号"-"可以替换为除了冒号的任意有效符号)
-- 2021/06/05 18:12:05
-- 21-06-05 18:12:05
-- 21/06/05 18:12:05
-- 2021年06月05日 --(不带时间,时间默认是00:00)
-- 2021年06月05日 18:12:05
-- 2012年03月08日 18小时30分钟50秒
-- 210605 --(即2021-06-05)
-- 20210605
-- 21-06-05
-- 2021-06-05
-- 20210605 18:12:00
-- 210605 18:12:00
-- 18:12, 18:12:05 --(不带日期,则取当前系统日期,没秒数自动补0)
----------------------------------------------------------------
function DateUtil.parseDateString(strTime)
local ret = 0
if not strTime then
print("parseDateString strTime is nil")
return ret
end
local textList = {} --数字字符列表
local symbolLen = 0 --特殊符号的长度
local isFirstMaoHao = false --首个字符是否冒号
local pStart = 1
local pFinal = 1
for i=1, #strTime do
local val = string.byte(strTime, i)
--截取数字的字符串列表,除去特殊字符
if val < 0x30 or val > 0x39 then
symbolLen = symbolLen + 1
if symbolLen == 1 and val == 0x3A then --是否冒号":"
isFirstMaoHao = true
end
pFinal = i
if pFinal > pStart then
local sub = string.sub(strTime, pStart, pFinal-1)
table.insert(textList, sub)
end
pStart = pFinal + 1
elseif i == #strTime then
--到结尾时,自动保存
if i >= pStart then
local sub = string.sub(strTime, pStart, i)
table.insert(textList, sub)
end
end
end
-- dump(textList, "textList")
local strYear, strMonth, strDay = "", "", ""
local strHour, strMin, strSec = "0", "0", "0"
local info = {year=0, month=0, day=0, hour=0, min=0, sec=0}
local textLen = #textList
if textLen == 0 then
print("parseDateString: not incluse digit", strTime)
return ret
end
local strFirst = textList[1]
if textLen == 1 then
if #strFirst == 8 then
--20210605 不带时间
strYear = string.sub(strFirst, 1, 4)
strMonth = string.sub(strFirst, 5, 6)
strDay = string.sub(strFirst, 7, 8)
elseif #strFirst == 6 then
--210605 不带时间
strYear = string.sub(strFirst, 1, 2)
strMonth = string.sub(strFirst, 3, 4)
strDay = string.sub(strFirst, 5, 6)
elseif #strFirst == 4 then
--2021 直接作为年份
strYear = strFirst
strMonth = "1"
strDay = "1"
else
print("parseDateString: wrong number of digits =", strTime)
return ret
end
else
if #strFirst == 6 then
--首个字符串是6个字符的日期 210605 18:12:00
strYear = string.sub(strFirst, 1, 2)
strMonth = string.sub(strFirst, 3, 4)
strDay = string.sub(strFirst, 5, 6)
if textLen >= 3 then
strHour = textList[2]
strMin = textList[3]
if textList[4] then
strSec = textList[4]
end
else
print("parseDateString: warning: first is 6bytes but textLen=", textLen)
end
elseif #strFirst == 8 then
--首个字符串是8个字符的日期 20210605 18:12:00
strYear = string.sub(strFirst, 1, 4)
strMonth = string.sub(strFirst, 5, 6)
strDay = string.sub(strFirst, 7, 8)
if textLen >= 3 then
strHour = textList[2]
strMin = textList[3]
if textList[4] then
strSec = textList[4]
end
else
print("parseDateString: warning: first is 8bytes but textLen=", textLen)
end
else
if textLen >= 5 then
-- 2021-06-05 18:12:00 2021-06-05 18:12
strYear = textList[1]
strMonth = textList[2]
strDay = textList[3]
strHour = textList[4]
strMin = textList[5]
strSec = textList[6] or "0"
elseif textLen >= 2 and textLen <= 4 then
if not isFirstMaoHao then
-- 21-06-05 2021-06-05
strYear = textList[1]
strMonth = textList[2]
strDay = textList[3] or "0"
else
-- 18:12 18:12:00 18:12:00.0
--首字符是冒号,取当前是时间
local tab = os.date("*t", os.time())
if tab then
strYear = tostring(tab.year)
strMonth = tostring(tab.month)
strDay = tostring(tab.day)
strHour = textList[1]
strMin = textList[2]
strSec = textList[3] or "0"
end
end
else
print("parseDateString: format err 2")
return ret
end
end
end
if #strYear > 0 then
--解析字符,检查格式
info.year = tonumber(strYear)
if not info.year then
print("parse err year=", strYear)
return ret
end
info.month = tonumber(strMonth)
if (not info.month) or info.month <= 0 or info.month > 12 then
print("parse err month=", strMonth)
return ret
end
info.day = tonumber(strDay)
if (not info.day) or info.day <= 0 or info.day > 31 then
print("parse err day=", strDay)
return ret
end
info.hour = tonumber(strHour)
if (not info.hour) or info.hour < 0 or info.hour > 24 then
print("parse err hour=", strHour)
return ret
end
info.min = tonumber(strMin)
if (not info.min) or info.min < 0 or info.min > 60 then
print("parse err min=", strMin)
return ret
end
info.sec = tonumber(strSec)
if (not info.sec) or info.sec < 0 or info.sec > 60 then
print("parse err sec=", strSec)
return ret
end
--两位年份,补到2000年
if info.year < 100 then
info.year = info.year + 2000
end
--转化为时间戳
ret = os.time(info) or 0;
-- dump(info, "parseDateString: info")
-- print("parseDateString: ret=", ret)
end
return ret
end
----------------------------------------------------------------
-- 解析时钟字符串的格式
-- 需要符合格式: 00:00, 10:10:00
-- 返回当前日期的时间戳数值,返回0是无效值
----------------------------------------------------------------
function DateUtil.parseSimpleClockTime(strTime)
local ret = 0
local strHour, strMin, strSec = nil, nil, nil
if strTime then
if #strTime == 5 or #strTime == 8 then
local digitCnt, mh = 0, 0
for i=1, #strTime do
local val = string.byte(strTime, i)
if val >= 0x30 and val <= 0x39 then
digitCnt = digitCnt + 1
elseif val == 0x3A then --冒号":"
mh = mh + 1
end
end
if #strTime == 5 then
if digitCnt == 4 and mh == 1 then
strHour = string.sub(strTime, 1, 2)
strMin = string.sub(strTime, 4, 6)
strSec = "0"
end
elseif #strTime == 8 then
if digitCnt == 6 and mh == 2 then
strHour = string.sub(strTime, 1, 2)
strMin = string.sub(strTime, 4, 5)
strSec = string.sub(strTime, 7, 8)
end
end
end
if strHour and strMin and strSec then
local hour = tonumber(strHour)
if (not hour) or (hour < 0) or (hour >= 24) then
print("hour err", strHour)
return ret
end
local min = tonumber(strMin)
if (not min) or (min < 0) or (min > 60) then
print("min err =", strMin)
return ret
end
local sec = tonumber(strSec)
if (not sec) or (sec < 0) or (sec > 60) then
print("sec err =", strSec)
return ret
end
local now = os.date("*t", os.time())
if now then
ret = os.time({ year = now.year, month=now.month, day=now.day, hour=hour, min=min, sec=sec}) or 0
end
end
end
return ret
end
--打印调试
function DateUtil.printDate(tag, time, isTimeFormat)
if tag and time then
if type(time) == "number" then
local str = (isTimeFormat) and DateUtil.getDateFomatString(time) or tostring(time)
print(tag .. " = " .. str)
elseif type(time) == "string" then
print(tag .. " = " .. time)
elseif type(time) == "table" then
local list = {}
for i,v in ipairs(time) do
if v then
table.insert(list, DateUtil.getDateFomatString(v))
end
end
dump(list, tag)
else
print(tag .. " = " .. tostring(time))
end
end
end
--测试代码
function DateUtil.test()
--当前时间
local now = DateUtil.getNowTime()
DateUtil.printDate("test: now num", now, false)
DateUtil.printDate("test: now string", DateUtil.getDateFomatString(now), true)
--测试日期差,距离国庆的天数
local toTime = DateUtil.getDateValueByTab({year=2021, month=10, day=1, hour=10, min=1, sec=0})
DateUtil.printDate("test: day num =", DateUtil.getDateNum(now, toTime), false)
-- 解析时间字符串为数值
DateUtil.printDate("test: parseDateString", DateUtil.parseDateString("2013/09/14 18:30:01"), true)
--日期显示不同格式
local curTime = DateUtil.getDateTimeValue(2013, 9, 14, 18, 30, 01)
DateUtil.printDate("getDateFomatString", DateUtil.getDateFomatString(curTime), true)
DateUtil.printDate("getDateSimpleString", DateUtil.getDateSimpleString(curTime), true)
DateUtil.printDate("getTimeFomatString", DateUtil.getTimeFomatString(curTime), true)
--显示年月日时分秒
DateUtil.printDate("getYear", DateUtil.getYear(now), false)
DateUtil.printDate("getMonth", DateUtil.getMonth(now), false)
DateUtil.printDate("getDay", DateUtil.getDay(now), false)
DateUtil.printDate("getHour", DateUtil.getHour(now), false)
DateUtil.printDate("getMin", DateUtil.getMin(now), false)
DateUtil.printDate("getSec", DateUtil.getSec(now), false)
--昨天,明天
DateUtil.printDate("getYesterDay", DateUtil.getYesterDay(now), true)
DateUtil.printDate("getTomorrowDate", DateUtil.getTomorrowDate(now), true)
--前几天,后几天
DateUtil.printDate("getBeforeDateByNum", DateUtil.getBeforeDateByNum(now, 3), true)
DateUtil.printDate("getAfterDateByNum", DateUtil.getAfterDateByNum(now, 3), true)
--前后日期的列表
DateUtil.printDate("getDayListFromYestoday", DateUtil.getDayListFromYestoday(now, 30), true)
DateUtil.printDate("getDayListFromTomorrow", DateUtil.getDayListFromTomorrow(now, 30), true)
--上个月,当前月,下个月 首天的时间值
DateUtil.printDate("getStartDateThisMonth", DateUtil.getStartDateThisMonth(now), true)
DateUtil.printDate("getStartDateNextMonth", DateUtil.getStartDateNextMonth(now), true)
DateUtil.printDate("getStartDatePrevMonth", DateUtil.getStartDatePrevMonth(now), true)
--当月有多少天
local nextTime = DateUtil.getDateTimeValue(2021, 10, 5, 20, 1, 2)
DateUtil.printDate("test: getMonthDayCount=", DateUtil.getMonthDayCount(nextTime), false)
--计算秒数
DateUtil.printDate("getDiffTime", DateUtil.getDiffTime(nextTime), false)
--打印一周时间
DateUtil.printDate("getWholeWeekDays", DateUtil.getWholeWeekDays(nextTime), true)
--季度的开始时间和结束时间
DateUtil.printDate("getFirstDayOfSeason", DateUtil.getFirstDayOfSeason(nextTime), true)
DateUtil.printDate("getLastDayOfSeason", DateUtil.getLastDayOfSeason(nextTime), true)
--一年有多少天
DateUtil.printDate("getYearDays", DateUtil.getYearDays(nextTime), false)
--在一年中的第几天
DateUtil.printDate("getDaysInYear", DateUtil.getDaysInYear(nextTime), false)
--剩余多少天
DateUtil.printDate("getRestDayOfYear", DateUtil.getRestDayOfYear(nextTime), false)
--日期是否相同
DateUtil.printDate("isSameDay", DateUtil.isSameDay(now, nextTime), false)
--日期是否有效
DateUtil.printDate("isValidDate", DateUtil.isValidDate("2020-09-01"), false)
--打印两个日期间的日子
DateUtil.printDate("getDateList", DateUtil.getDateList(now, nextTime), false)
--对比时间
DateUtil.printDate("compareDayString", DateUtil.compareDayString("2020-09-01", "2020-09-02"), false)
DateUtil.printDate("compareDayWithSystem", DateUtil.compareDayWithSystem("2021-09-12"), false)
DateUtil.printDate("compareClockTimeString", DateUtil.compareClockTimeString("18:00", "06:00"), false)
DateUtil.printDate("compareClockTimeWithSystem", DateUtil.compareClockTimeWithSystem("18:20"), false)
end