lua 日期时间处理工具类

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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值