Files
BR_YKC/4G/code/lib/common.lua
2026-03-31 15:46:04 +08:00

309 lines
8.9 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.
---模块功能:通用库函数、编码格式转换、时区时间转换
-- @module common
-- @author openLuat
-- @license MIT
-- @copyright openLuat
-- @release 2017.02.20
--定义模块,导入依赖库
module(..., package.seeall)
--加载常用的全局函数至本地
local tinsert, ssub, sbyte, schar, sformat, slen = table.insert, string.sub, string.byte, string.char, string.format, string.len
--- ascii字符串的unicode编码的16进制字符串 转化为 ascii字符串
-- @string inNum 待转换字符串
-- @return string data转换后的字符串
-- @usage
-- local data = common.ucs2ToAscii("0031003200330034")
-- data is "1234"
function ucs2ToAscii(inNum)
local tonum = {}
for i = 1, slen(inNum), 4 do
tinsert(tonum, tonumber(ssub(inNum, i, i + 3), 16) % 256)
end
return schar(unpack(tonum))
end
--- ascii字符串 转化为 ascii字符串的unicode编码的16进制字符串(仅支持数字和+)
-- @string inNum 待转换字符串
-- @return string data,转换后的字符串
-- @usage
-- local data = common.nstrToUcs2Hex("+1234")
-- data is "002B0031003200330034"
function nstrToUcs2Hex(inNum)
local hexs = ""
local elem = ""
for i = 1, slen(inNum) do
elem = ssub(inNum, i, i)
if elem == "+" then
hexs = hexs .. "002B"
else
hexs = hexs .. "003" .. elem
end
end
return hexs
end
--- ASCII字符串 转化为 BCD编码格式字符串(仅支持数字)
-- @string inStr 待转换字符串
-- @number destLen 转换后的字符串期望长度如果实际不足则填充F
-- @return string data,转换后的字符串
-- @usage
-- local data = common.numToBcdNum("8618126324567")
-- data is "688121364265f7" 表示第1个字节是0x68第2个字节为0x81......
function numToBcdNum(inStr,destLen)
local l,t,num = string.len(inStr or ""),{}
destLen = destLen or (inStr:len()+1)/2
for i=1,l,2 do
num = tonumber(inStr:sub(i,i+1),16)
if i==l then
num = 0xf0+num
else
num = (num%0x10)*0x10 + (num-(num%0x10))/0x10
end
table.insert(t,num)
end
local s = string.char(unpack(t))
l = slen(s)
if l < destLen then
s = s .. string.rep("\255",destLen-l)
elseif l > destLen then
s = ssub(s,1,destLen)
end
return s
end
--- BCD编码格式字符串 转化为 号码ASCII字符串(仅支持数字)
-- @string num 待转换字符串
-- @return string data,转换后的字符串
-- @usage
-- local data = common.bcdNumToNum(common.fromHex("688121364265f7")) --表示第1个字节是0x68第2个字节为0x81......
-- data is "8618126324567"
function bcdNumToNum(num)
local byte,v1,v2
local t = {}
for i=1,num:len() do
byte = num:byte(i)
v1,v2 = bit.band(byte,0x0f),bit.band(bit.rshift(byte,4),0x0f)
if v1 == 0x0f then break end
table.insert(t,v1)
if v2 == 0x0f then break end
table.insert(t,v2)
end
return table.concat(t)
end
--- unicode小端编码 转化为 gb2312编码
-- @string ucs2s unicode小端编码数据
-- @return string data,gb2312编码数据
-- @usage local data = common.ucs2ToGb2312(ucs2s)
function ucs2ToGb2312(ucs2s)
local cd = iconv.open("gb2312", "ucs2")
return cd:iconv(ucs2s)
end
--- gb2312编码 转化为 unicode小端编码
-- @string gb2312s gb2312编码数据
-- @return string data,unicode小端编码数据
-- @usage local data = common.gb2312ToUcs2(gb2312s)
function gb2312ToUcs2(gb2312s)
local cd = iconv.open("ucs2", "gb2312")
return cd:iconv(gb2312s)
end
--- unicode大端编码 转化为 gb2312编码
-- @string ucs2s unicode大端编码数据
-- @return string data,gb2312编码数据
-- @usage data = common.ucs2beToGb2312(ucs2s)
function ucs2beToGb2312(ucs2s)
local cd = iconv.open("gb2312", "ucs2be")
return cd:iconv(ucs2s)
end
--- gb2312编码 转化为 unicode大端编码
-- @string gb2312s gb2312编码数据
-- @return string data,unicode大端编码数据
-- @usage local data = common.gb2312ToUcs2be(gb2312s)
function gb2312ToUcs2be(gb2312s)
local cd = iconv.open("ucs2be", "gb2312")
return cd:iconv(gb2312s)
end
--- unicode小端编码 转化为 utf8编码
-- @string ucs2s unicode小端编码数据
-- @return string data,utf8编码数据
-- @usage data = common.ucs2ToUtf8(ucs2s)
function ucs2ToUtf8(ucs2s)
local cd = iconv.open("utf8", "ucs2")
return cd:iconv(ucs2s)
end
--- utf8编码 转化为 unicode小端编码
-- @string utf8s utf8编码数据
-- @return string data,unicode小端编码数据
-- @usage local data = common.utf8ToUcs2(utf8s)
function utf8ToUcs2(utf8s)
local cd = iconv.open("ucs2", "utf8")
return cd:iconv(utf8s)
end
--- unicode大端编码 转化为 utf8编码
-- @string ucs2s unicode大端编码数据
-- @return string data,utf8编码数据
-- @usage data = common.ucs2beToUtf8(ucs2s)
function ucs2beToUtf8(ucs2s)
local cd = iconv.open("utf8", "ucs2be")
return cd:iconv(ucs2s)
end
--- utf8编码 转化为 unicode大端编码
-- @string utf8s utf8编码数据
-- @return string data,unicode大端编码数据
-- @usage local data = common.utf8ToUcs2be(utf8s)
function utf8ToUcs2be(utf8s)
local cd = iconv.open("ucs2be", "utf8")
return cd:iconv(utf8s)
end
--- utf8编码 转化为 gb2312编码
-- @string utf8s utf8编码数据
-- @return string data,gb2312编码数据
-- @usage local data = common.utf8ToGb2312(utf8s)
function utf8ToGb2312(utf8s)
local cd = iconv.open("ucs2", "utf8")
local ucs2s = cd:iconv(utf8s)
cd = iconv.open("gb2312", "ucs2")
return cd:iconv(ucs2s)
end
--- gb2312编码 转化为 utf8编码
-- @string gb2312s gb2312编码数据
-- @return string data,utf8编码数据
-- @usage local data = common.gb2312ToUtf8(gb2312s)
function gb2312ToUtf8(gb2312s)
local cd = iconv.open("ucs2", "gb2312")
local ucs2s = cd:iconv(gb2312s)
cd = iconv.open("utf8", "ucs2")
return cd:iconv(ucs2s)
end
local function timeAddzone(y, m, d, hh, mm, ss, zone)
if not y or not m or not d or not hh or not mm or not ss then
return
end
hh = hh + zone
if hh >= 24 then
hh = hh - 24
d = d + 1
if m == 4 or m == 6 or m == 9 or m == 11 then
if d > 30 then
d = 1
m = m + 1
end
elseif m == 1 or m == 3 or m == 5 or m == 7 or m == 8 or m == 10 then
if d > 31 then
d = 1
m = m + 1
end
elseif m == 12 then
if d > 31 then
d = 1
m = 1
y = y + 1
end
elseif m == 2 then
if (((y + 2000) % 400) == 0) or (((y + 2000) % 4 == 0) and ((y + 2000) % 100 ~= 0)) then
if d > 29 then
d = 1
m = 3
end
else
if d > 28 then
d = 1
m = 3
end
end
end
end
local t = {}
t.year, t.month, t.day, t.hour, t.min, t.sec = y, m, d, hh, mm, ss
return t
end
local function timeSubZone(y, m, d, hh, mm, ss, zone)
if not y or not m or not d or not hh or not mm or not ss then
return
end
hh = hh + zone
if hh < 0 then
hh = hh + 24
d = d - 1
if m == 2 or m == 4 or m == 6 or m == 8 or m == 9 or m == 11 then
if d < 1 then
d = 31
m = m - 1
end
elseif m == 5 or m == 7 or m == 10 or m == 12 then
if d < 1 then
d = 30
m = m - 1
end
elseif m == 1 then
if d < 1 then
d = 31
m = 12
y = y - 1
end
elseif m == 3 then
if (((y + 2000) % 400) == 0) or (((y + 2000) % 4 == 0) and ((y + 2000) % 100 ~= 0)) then
if d < 1 then
d = 29
m = 2
end
else
if d < 1 then
d = 28
m = 2
end
end
end
end
local t = {}
t.year, t.month, t.day, t.hour, t.min, t.sec = y, m, d, hh, mm, ss
return t
end
--- 时区时间转换
-- @number y 源时区年份
-- @number m 源时区月份
-- @number d 源时区天
-- @number hh 源时区小时
-- @number mm 源时区分
-- @number ss 源时区秒
-- @number srcTimeZone 源时区
-- @number dstTimeZone 目的时区
-- @return table dstZoneTime,返回目的时区对应的时间,{year,month,day,hour,min,sec}
-- @usage
-- local dstZoneTime = common.timeZoneConvert(2018,1,1,18,00,00,0,8)
-- dstZoneTime为{year=2018,month=1,day=2,hour=2,min=0,sec=0}
function timeZoneConvert(y, m, d, hh, mm, ss, srcTimeZone, dstTimeZone)
local t = {}
local zone = dstTimeZone-srcTimeZone
if zone >= 0 and zone < 23 then
t = timeAddzone(y, m, d, hh, mm, ss, zone)
elseif zone < 0 and zone >= -24 then
t = timeSubZone(y, m, d, hh, mm, ss, zone)
end
return t
end