common.lua 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. ---模块功能:通用库函数、编码格式转换、时区时间转换
  2. -- @module common
  3. -- @author openLuat
  4. -- @license MIT
  5. -- @copyright openLuat
  6. -- @release 2017.02.20
  7. --定义模块,导入依赖库
  8. module(..., package.seeall)
  9. --加载常用的全局函数至本地
  10. local tinsert, ssub, sbyte, schar, sformat, slen = table.insert, string.sub, string.byte, string.char, string.format, string.len
  11. --- ascii字符串的unicode编码的16进制字符串 转化为 ascii字符串
  12. -- @string inNum 待转换字符串
  13. -- @return string data,转换后的字符串
  14. -- @usage
  15. -- local data = common.ucs2ToAscii("0031003200330034")
  16. -- data is "1234"
  17. function ucs2ToAscii(inNum)
  18. local tonum = {}
  19. for i = 1, slen(inNum), 4 do
  20. tinsert(tonum, tonumber(ssub(inNum, i, i + 3), 16) % 256)
  21. end
  22. return schar(unpack(tonum))
  23. end
  24. --- ascii字符串 转化为 ascii字符串的unicode编码的16进制字符串(仅支持数字和+)
  25. -- @string inNum 待转换字符串
  26. -- @return string data,转换后的字符串
  27. -- @usage
  28. -- local data = common.nstrToUcs2Hex("+1234")
  29. -- data is "002B0031003200330034"
  30. function nstrToUcs2Hex(inNum)
  31. local hexs = ""
  32. local elem = ""
  33. for i = 1, slen(inNum) do
  34. elem = ssub(inNum, i, i)
  35. if elem == "+" then
  36. hexs = hexs .. "002B"
  37. else
  38. hexs = hexs .. "003" .. elem
  39. end
  40. end
  41. return hexs
  42. end
  43. --- ASCII字符串 转化为 BCD编码格式字符串(仅支持数字)
  44. -- @string inStr 待转换字符串
  45. -- @number destLen 转换后的字符串期望长度,如果实际不足,则填充F
  46. -- @return string data,转换后的字符串
  47. -- @usage
  48. -- local data = common.numToBcdNum("8618126324567")
  49. -- data is "688121364265f7" (表示第1个字节是0x68,第2个字节为0x81,......)
  50. function numToBcdNum(inStr,destLen)
  51. local l,t,num = string.len(inStr or ""),{}
  52. destLen = destLen or (inStr:len()+1)/2
  53. for i=1,l,2 do
  54. num = tonumber(inStr:sub(i,i+1),16)
  55. if i==l then
  56. num = 0xf0+num
  57. else
  58. num = (num%0x10)*0x10 + (num-(num%0x10))/0x10
  59. end
  60. table.insert(t,num)
  61. end
  62. local s = string.char(unpack(t))
  63. l = slen(s)
  64. if l < destLen then
  65. s = s .. string.rep("\255",destLen-l)
  66. elseif l > destLen then
  67. s = ssub(s,1,destLen)
  68. end
  69. return s
  70. end
  71. --- BCD编码格式字符串 转化为 号码ASCII字符串(仅支持数字)
  72. -- @string num 待转换字符串
  73. -- @return string data,转换后的字符串
  74. -- @usage
  75. -- local data = common.bcdNumToNum(common.fromHex("688121364265f7")) --表示第1个字节是0x68,第2个字节为0x81,......
  76. -- data is "8618126324567"
  77. function bcdNumToNum(num)
  78. local byte,v1,v2
  79. local t = {}
  80. for i=1,num:len() do
  81. byte = num:byte(i)
  82. v1,v2 = bit.band(byte,0x0f),bit.band(bit.rshift(byte,4),0x0f)
  83. if v1 == 0x0f then break end
  84. table.insert(t,v1)
  85. if v2 == 0x0f then break end
  86. table.insert(t,v2)
  87. end
  88. return table.concat(t)
  89. end
  90. --- unicode小端编码 转化为 gb2312编码
  91. -- @string ucs2s unicode小端编码数据
  92. -- @return string data,gb2312编码数据
  93. -- @usage local data = common.ucs2ToGb2312(ucs2s)
  94. function ucs2ToGb2312(ucs2s)
  95. local cd = iconv.open("gb2312", "ucs2")
  96. return cd:iconv(ucs2s)
  97. end
  98. --- gb2312编码 转化为 unicode小端编码
  99. -- @string gb2312s gb2312编码数据
  100. -- @return string data,unicode小端编码数据
  101. -- @usage local data = common.gb2312ToUcs2(gb2312s)
  102. function gb2312ToUcs2(gb2312s)
  103. local cd = iconv.open("ucs2", "gb2312")
  104. return cd:iconv(gb2312s)
  105. end
  106. --- unicode大端编码 转化为 gb2312编码
  107. -- @string ucs2s unicode大端编码数据
  108. -- @return string data,gb2312编码数据
  109. -- @usage data = common.ucs2beToGb2312(ucs2s)
  110. function ucs2beToGb2312(ucs2s)
  111. local cd = iconv.open("gb2312", "ucs2be")
  112. return cd:iconv(ucs2s)
  113. end
  114. --- gb2312编码 转化为 unicode大端编码
  115. -- @string gb2312s gb2312编码数据
  116. -- @return string data,unicode大端编码数据
  117. -- @usage local data = common.gb2312ToUcs2be(gb2312s)
  118. function gb2312ToUcs2be(gb2312s)
  119. local cd = iconv.open("ucs2be", "gb2312")
  120. return cd:iconv(gb2312s)
  121. end
  122. --- unicode小端编码 转化为 utf8编码
  123. -- @string ucs2s unicode小端编码数据
  124. -- @return string data,utf8编码数据
  125. -- @usage data = common.ucs2ToUtf8(ucs2s)
  126. function ucs2ToUtf8(ucs2s)
  127. local cd = iconv.open("utf8", "ucs2")
  128. return cd:iconv(ucs2s)
  129. end
  130. --- utf8编码 转化为 unicode小端编码
  131. -- @string utf8s utf8编码数据
  132. -- @return string data,unicode小端编码数据
  133. -- @usage local data = common.utf8ToUcs2(utf8s)
  134. function utf8ToUcs2(utf8s)
  135. local cd = iconv.open("ucs2", "utf8")
  136. return cd:iconv(utf8s)
  137. end
  138. --- unicode大端编码 转化为 utf8编码
  139. -- @string ucs2s unicode大端编码数据
  140. -- @return string data,utf8编码数据
  141. -- @usage data = common.ucs2beToUtf8(ucs2s)
  142. function ucs2beToUtf8(ucs2s)
  143. local cd = iconv.open("utf8", "ucs2be")
  144. return cd:iconv(ucs2s)
  145. end
  146. --- utf8编码 转化为 unicode大端编码
  147. -- @string utf8s utf8编码数据
  148. -- @return string data,unicode大端编码数据
  149. -- @usage local data = common.utf8ToUcs2be(utf8s)
  150. function utf8ToUcs2be(utf8s)
  151. local cd = iconv.open("ucs2be", "utf8")
  152. return cd:iconv(utf8s)
  153. end
  154. --- utf8编码 转化为 gb2312编码
  155. -- @string utf8s utf8编码数据
  156. -- @return string data,gb2312编码数据
  157. -- @usage local data = common.utf8ToGb2312(utf8s)
  158. function utf8ToGb2312(utf8s)
  159. local cd = iconv.open("ucs2", "utf8")
  160. local ucs2s = cd:iconv(utf8s)
  161. cd = iconv.open("gb2312", "ucs2")
  162. return cd:iconv(ucs2s)
  163. end
  164. --- gb2312编码 转化为 utf8编码
  165. -- @string gb2312s gb2312编码数据
  166. -- @return string data,utf8编码数据
  167. -- @usage local data = common.gb2312ToUtf8(gb2312s)
  168. function gb2312ToUtf8(gb2312s)
  169. local cd = iconv.open("ucs2", "gb2312")
  170. local ucs2s = cd:iconv(gb2312s)
  171. cd = iconv.open("utf8", "ucs2")
  172. return cd:iconv(ucs2s)
  173. end
  174. local function timeAddzone(y, m, d, hh, mm, ss, zone)
  175. if not y or not m or not d or not hh or not mm or not ss then
  176. return
  177. end
  178. hh = hh + zone
  179. if hh >= 24 then
  180. hh = hh - 24
  181. d = d + 1
  182. if m == 4 or m == 6 or m == 9 or m == 11 then
  183. if d > 30 then
  184. d = 1
  185. m = m + 1
  186. end
  187. elseif m == 1 or m == 3 or m == 5 or m == 7 or m == 8 or m == 10 then
  188. if d > 31 then
  189. d = 1
  190. m = m + 1
  191. end
  192. elseif m == 12 then
  193. if d > 31 then
  194. d = 1
  195. m = 1
  196. y = y + 1
  197. end
  198. elseif m == 2 then
  199. if (((y + 2000) % 400) == 0) or (((y + 2000) % 4 == 0) and ((y + 2000) % 100 ~= 0)) then
  200. if d > 29 then
  201. d = 1
  202. m = 3
  203. end
  204. else
  205. if d > 28 then
  206. d = 1
  207. m = 3
  208. end
  209. end
  210. end
  211. end
  212. local t = {}
  213. t.year, t.month, t.day, t.hour, t.min, t.sec = y, m, d, hh, mm, ss
  214. return t
  215. end
  216. local function timeSubZone(y, m, d, hh, mm, ss, zone)
  217. if not y or not m or not d or not hh or not mm or not ss then
  218. return
  219. end
  220. hh = hh + zone
  221. if hh < 0 then
  222. hh = hh + 24
  223. d = d - 1
  224. if m == 2 or m == 4 or m == 6 or m == 8 or m == 9 or m == 11 then
  225. if d < 1 then
  226. d = 31
  227. m = m - 1
  228. end
  229. elseif m == 5 or m == 7 or m == 10 or m == 12 then
  230. if d < 1 then
  231. d = 30
  232. m = m - 1
  233. end
  234. elseif m == 1 then
  235. if d < 1 then
  236. d = 31
  237. m = 12
  238. y = y - 1
  239. end
  240. elseif m == 3 then
  241. if (((y + 2000) % 400) == 0) or (((y + 2000) % 4 == 0) and ((y + 2000) % 100 ~= 0)) then
  242. if d < 1 then
  243. d = 29
  244. m = 2
  245. end
  246. else
  247. if d < 1 then
  248. d = 28
  249. m = 2
  250. end
  251. end
  252. end
  253. end
  254. local t = {}
  255. t.year, t.month, t.day, t.hour, t.min, t.sec = y, m, d, hh, mm, ss
  256. return t
  257. end
  258. --- 时区时间转换
  259. -- @number y 源时区年份
  260. -- @number m 源时区月份
  261. -- @number d 源时区天
  262. -- @number hh 源时区小时
  263. -- @number mm 源时区分
  264. -- @number ss 源时区秒
  265. -- @number srcTimeZone 源时区
  266. -- @number dstTimeZone 目的时区
  267. -- @return table dstZoneTime,返回目的时区对应的时间,{year,month,day,hour,min,sec}
  268. -- @usage
  269. -- local dstZoneTime = common.timeZoneConvert(2018,1,1,18,00,00,0,8)
  270. -- dstZoneTime为{year=2018,month=1,day=2,hour=2,min=0,sec=0}
  271. function timeZoneConvert(y, m, d, hh, mm, ss, srcTimeZone, dstTimeZone)
  272. local t = {}
  273. local zone = dstTimeZone-srcTimeZone
  274. if zone >= 0 and zone < 23 then
  275. t = timeAddzone(y, m, d, hh, mm, ss, zone)
  276. elseif zone < 0 and zone >= -24 then
  277. t = timeSubZone(y, m, d, hh, mm, ss, zone)
  278. end
  279. return t
  280. end