lua日期时间字符解析

lua日期时间字符解析

下面介绍一种强大的日期时间字符解析方法,传入日期字符,返回数字类型的时间戳。由于日期格式 是多种多样的,日期字符的解析很难通过正则表达式来统一处理,例如:格式1是“2021-06-05 18:12:05 ”,而格式2是“2021/06/05”, 两种格式有差别,解析起来特别麻烦, 为此写了一个解析方法,基本到满足大部分的日期格式需求,如不满足可在此基础上修改。

解析字符需要符合以下格式:
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日
2021年06月05日 18:12:05
2012年03月08日 18小时30分钟50秒
210605 --即2021-06-05,时间默认是(00:00)
20210605
21-06-05
2021-06-05
20210605 18:12:00
210605 18:12:00
18:12, 18:12:05 --也可以时间格式,取当天的日期

实现思想:通过提取格式里的数字字符串列表,除去特殊字符,然后对数字字符串列表进行统一识别和处理。

代码如下:

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())
                    strYear = tostring(tab.year)
                    strMonth = tostring(tab.month)
                    strDay = tostring(tab.day)

                    strHour = textList[1]
                    strMin = textList[2]
                    strSec = textList[3] or "0"
                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

测试代码

function DateUtil.test()
    local time = DateUtil.parseDateString("2020/09/01 18:30:56")
    print("parseDateString time=", os.date("%Y-%m-%d %H:%M:%S", time))
end
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值