toStringDate.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. var staticParseInt = require('./staticParseInt')
  2. var helperGetUTCDateTime = require('./helperGetUTCDateTime')
  3. var helperGetDateTime = require('./helperGetDateTime')
  4. var isString = require('./isString')
  5. var isDate = require('./isDate')
  6. function getParseRule (txt) {
  7. return '(\\d{' + txt + '})'
  8. }
  9. function toParseMs (num) {
  10. if (num < 10) {
  11. return num * 100
  12. } else if (num < 100) {
  13. return num * 10
  14. }
  15. return num
  16. }
  17. function toParseNum (num) {
  18. return isNaN(num) ? num : staticParseInt(num)
  19. }
  20. var d2 = getParseRule(2)
  21. var d1or2 = getParseRule('1,2')
  22. var d1or7 = getParseRule('1,7')
  23. var d3or4 = getParseRule('3,4')
  24. var place = '.{1}'
  25. var d1Or2RE = place + d1or2
  26. var dzZ = '(([zZ])|([-+]\\d{2}:?\\d{2}))'
  27. var defaulParseStrs = [d3or4, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, place + d1or7, dzZ]
  28. var defaulParseREs = []
  29. for (var len = defaulParseStrs.length - 1; len >= 0; len--) {
  30. var rule = ''
  31. for (var i = 0; i < len + 1; i++) {
  32. rule += defaulParseStrs[i]
  33. }
  34. defaulParseREs.push(new RegExp('^' + rule + '$'))
  35. }
  36. /**
  37. * 解析默认格式
  38. */
  39. function parseDefaultRules (str) {
  40. var matchRest, resMaps = {}
  41. for (var i = 0, dfrLen = defaulParseREs.length; i < dfrLen; i++) {
  42. matchRest = str.match(defaulParseREs[i])
  43. if (matchRest) {
  44. resMaps.y = matchRest[1]
  45. resMaps.M = matchRest[2]
  46. resMaps.d = matchRest[3]
  47. resMaps.H = matchRest[4]
  48. resMaps.m = matchRest[5]
  49. resMaps.s = matchRest[6]
  50. resMaps.S = matchRest[7]
  51. resMaps.Z = matchRest[8]
  52. break
  53. }
  54. }
  55. return resMaps
  56. }
  57. var customParseStrs = [
  58. ['yyyy', d3or4],
  59. ['yy', d2],
  60. ['MM', d2],
  61. ['M', d1or2],
  62. ['dd', d2],
  63. ['d', d1or2],
  64. ['HH', d2],
  65. ['H', d1or2],
  66. ['mm', d2],
  67. ['m', d1or2],
  68. ['ss', d2],
  69. ['s', d1or2],
  70. ['SSS', getParseRule(3)],
  71. ['S', d1or7],
  72. ['Z', dzZ]
  73. ]
  74. var parseRuleMaps = {}
  75. var parseRuleKeys = ['\\[([^\\]]+)\\]']
  76. for (var i = 0; i < customParseStrs.length; i++) {
  77. var itemRule = customParseStrs[i]
  78. parseRuleMaps[itemRule[0]] = itemRule[1] + '?'
  79. parseRuleKeys.push(itemRule[0])
  80. }
  81. var customParseRes = new RegExp(parseRuleKeys.join('|'), 'g')
  82. var cacheFormatMaps = {}
  83. /**
  84. * 解析自定义格式
  85. */
  86. function parseCustomRules (str, format) {
  87. var cacheItem = cacheFormatMaps[format]
  88. if (!cacheItem) {
  89. var posIndexs = []
  90. var re = format.replace(/([$(){}*+.?\\^|])/g, "\\$1").replace(customParseRes, function (text, val) {
  91. var firstChar = text.charAt(0)
  92. // 如果为转义符号:[关键字]
  93. if (firstChar === '[') {
  94. return val
  95. }
  96. posIndexs.push(firstChar)
  97. return parseRuleMaps[text]
  98. })
  99. cacheItem = cacheFormatMaps[format] = {
  100. _i: posIndexs,
  101. _r: new RegExp(re)
  102. }
  103. }
  104. var resMaps = {}
  105. var matchRest = str.match(cacheItem._r)
  106. if (matchRest) {
  107. var _i = cacheItem._i
  108. for (var i = 1, len = matchRest.length; i < len; i++) {
  109. resMaps[_i[i - 1]] = matchRest[i]
  110. }
  111. return resMaps
  112. }
  113. return resMaps
  114. }
  115. /**
  116. * 解析时区
  117. */
  118. function parseTimeZone (resMaps) {
  119. // 如果为UTC 时间
  120. if (/^[zZ]/.test(resMaps.Z)) {
  121. return new Date(helperGetUTCDateTime(resMaps))
  122. } else {
  123. // 如果指定时区,时区转换
  124. var matchRest = resMaps.Z.match(/([-+])(\d{2}):?(\d{2})/)
  125. if (matchRest) {
  126. return new Date(helperGetUTCDateTime(resMaps) - (matchRest[1] === '-' ? -1 : 1) * staticParseInt(matchRest[2]) * 3600000 + staticParseInt(matchRest[3]) * 60000)
  127. }
  128. }
  129. return new Date('')
  130. }
  131. /**
  132. * 字符串转为日期
  133. *
  134. * @param {String/Number/Date} str 日期或数字
  135. * @param {String} format 解析日期格式(yyyy年份、MM月份、dd天、hh(12)HH(24)小时、mm分钟、ss秒、SSS毫秒、Z时区)
  136. * @return {Date}
  137. */
  138. function toStringDate (str, format) {
  139. if (str) {
  140. var isDType = isDate(str)
  141. if (isDType || (!format && /^[0-9]{11,15}$/.test(str))) {
  142. return new Date(isDType ? helperGetDateTime(str) : staticParseInt(str))
  143. }
  144. if (isString(str)) {
  145. var resMaps = format ? parseCustomRules(str, format) : parseDefaultRules(str)
  146. if (resMaps.y) {
  147. if (resMaps.M) {
  148. resMaps.M = toParseNum(resMaps.M) - 1
  149. }
  150. if (resMaps.S) {
  151. // 如果7位则是微秒,只精确到3位毫秒
  152. resMaps.S = toParseMs(toParseNum(resMaps.S.substring(0, 3)))
  153. }
  154. if (resMaps.Z) {
  155. return parseTimeZone(resMaps)
  156. } else {
  157. return new Date(resMaps.y, resMaps.M || 0, resMaps.d || 1, resMaps.H || 0, resMaps.m || 0, resMaps.s || 0, resMaps.S || 0)
  158. }
  159. }
  160. }
  161. }
  162. return new Date('')
  163. }
  164. module.exports = toStringDate