181 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var staticParseInt = require('./staticParseInt')
 | 
						||
 | 
						||
var helperGetUTCDateTime = require('./helperGetUTCDateTime')
 | 
						||
var helperGetDateTime = require('./helperGetDateTime')
 | 
						||
 | 
						||
var isString = require('./isString')
 | 
						||
var isDate = require('./isDate')
 | 
						||
 | 
						||
function getParseRule (txt) {
 | 
						||
  return '(\\d{' + txt + '})'
 | 
						||
}
 | 
						||
 | 
						||
function toParseMs (num) {
 | 
						||
  if (num < 10) {
 | 
						||
    return num * 100
 | 
						||
  } else if (num < 100) {
 | 
						||
    return num * 10
 | 
						||
  }
 | 
						||
  return num
 | 
						||
}
 | 
						||
 | 
						||
function toParseNum (num) {
 | 
						||
  return isNaN(num) ? num : staticParseInt(num)
 | 
						||
}
 | 
						||
 | 
						||
var d2 = getParseRule(2)
 | 
						||
var d1or2 = getParseRule('1,2')
 | 
						||
var d1or7 = getParseRule('1,7')
 | 
						||
var d3or4 = getParseRule('3,4')
 | 
						||
var place = '.{1}'
 | 
						||
var d1Or2RE = place + d1or2
 | 
						||
var dzZ = '(([zZ])|([-+]\\d{2}:?\\d{2}))'
 | 
						||
 | 
						||
var defaulParseStrs = [d3or4, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, d1Or2RE, place + d1or7, dzZ]
 | 
						||
var defaulParseREs = []
 | 
						||
 | 
						||
for (var len = defaulParseStrs.length - 1; len >= 0; len--) {
 | 
						||
  var rule = ''
 | 
						||
  for (var i = 0; i < len + 1; i++) {
 | 
						||
    rule += defaulParseStrs[i]
 | 
						||
  }
 | 
						||
  defaulParseREs.push(new RegExp('^' + rule + '$'))
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * 解析默认格式
 | 
						||
 */
 | 
						||
function parseDefaultRules (str) {
 | 
						||
  var matchRest, resMaps = {}
 | 
						||
  for (var i = 0, dfrLen = defaulParseREs.length; i < dfrLen; i++) {
 | 
						||
    matchRest = str.match(defaulParseREs[i])
 | 
						||
    if (matchRest) {
 | 
						||
      resMaps.y = matchRest[1]
 | 
						||
      resMaps.M = matchRest[2]
 | 
						||
      resMaps.d = matchRest[3]
 | 
						||
      resMaps.H = matchRest[4]
 | 
						||
      resMaps.m = matchRest[5]
 | 
						||
      resMaps.s = matchRest[6]
 | 
						||
      resMaps.S = matchRest[7]
 | 
						||
      resMaps.Z = matchRest[8]
 | 
						||
      break
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return resMaps
 | 
						||
}
 | 
						||
 | 
						||
var customParseStrs = [
 | 
						||
  ['yyyy', d3or4],
 | 
						||
  ['yy', d2],
 | 
						||
  ['MM', d2],
 | 
						||
  ['M', d1or2],
 | 
						||
  ['dd', d2],
 | 
						||
  ['d', d1or2],
 | 
						||
  ['HH', d2],
 | 
						||
  ['H', d1or2],
 | 
						||
  ['mm', d2],
 | 
						||
  ['m', d1or2],
 | 
						||
  ['ss', d2],
 | 
						||
  ['s', d1or2],
 | 
						||
  ['SSS', getParseRule(3)],
 | 
						||
  ['S', d1or7],
 | 
						||
  ['Z', dzZ]
 | 
						||
]
 | 
						||
var parseRuleMaps = {}
 | 
						||
var parseRuleKeys = ['\\[([^\\]]+)\\]']
 | 
						||
 | 
						||
for (var i = 0; i < customParseStrs.length; i++) {
 | 
						||
  var itemRule = customParseStrs[i]
 | 
						||
  parseRuleMaps[itemRule[0]] = itemRule[1] + '?'
 | 
						||
  parseRuleKeys.push(itemRule[0])
 | 
						||
}
 | 
						||
 | 
						||
var customParseRes = new RegExp(parseRuleKeys.join('|'), 'g')
 | 
						||
var cacheFormatMaps = {}
 | 
						||
 | 
						||
/**
 | 
						||
 * 解析自定义格式
 | 
						||
 */
 | 
						||
function parseCustomRules (str, format) {
 | 
						||
  var cacheItem = cacheFormatMaps[format]
 | 
						||
  if (!cacheItem) {
 | 
						||
    var posIndexs = []
 | 
						||
    var re = format.replace(/([$(){}*+.?\\^|])/g, "\\$1").replace(customParseRes, function (text, val) {
 | 
						||
      var firstChar = text.charAt(0)
 | 
						||
      // 如果为转义符号:[关键字]
 | 
						||
      if (firstChar === '[') {
 | 
						||
        return val
 | 
						||
      }
 | 
						||
      posIndexs.push(firstChar)
 | 
						||
      return parseRuleMaps[text]
 | 
						||
    })
 | 
						||
    cacheItem = cacheFormatMaps[format] = {
 | 
						||
      _i: posIndexs,
 | 
						||
      _r: new RegExp(re)
 | 
						||
    }
 | 
						||
  }
 | 
						||
  var resMaps = {}
 | 
						||
  var matchRest = str.match(cacheItem._r)
 | 
						||
  if (matchRest) {
 | 
						||
    var _i = cacheItem._i
 | 
						||
    for (var i = 1, len = matchRest.length; i < len; i++) {
 | 
						||
      resMaps[_i[i - 1]] = matchRest[i]
 | 
						||
    }
 | 
						||
    return resMaps
 | 
						||
  }
 | 
						||
  return resMaps
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
 * 解析时区
 | 
						||
 */
 | 
						||
function parseTimeZone (resMaps) {
 | 
						||
  // 如果为UTC 时间
 | 
						||
  if (/^[zZ]/.test(resMaps.Z)) {
 | 
						||
    return new Date(helperGetUTCDateTime(resMaps))
 | 
						||
  } else {
 | 
						||
    // 如果指定时区,时区转换
 | 
						||
    var matchRest = resMaps.Z.match(/([-+])(\d{2}):?(\d{2})/)
 | 
						||
    if (matchRest) {
 | 
						||
      return new Date(helperGetUTCDateTime(resMaps) - (matchRest[1] === '-' ? -1 : 1) * staticParseInt(matchRest[2]) * 3600000 + staticParseInt(matchRest[3]) * 60000)
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return new Date('')
 | 
						||
}
 | 
						||
 | 
						||
/**
 | 
						||
  * 字符串转为日期
 | 
						||
  *
 | 
						||
  * @param {String/Number/Date} str 日期或数字
 | 
						||
  * @param {String} format 解析日期格式(yyyy年份、MM月份、dd天、hh(12)HH(24)小时、mm分钟、ss秒、SSS毫秒、Z时区)
 | 
						||
  * @return {Date}
 | 
						||
  */
 | 
						||
function toStringDate (str, format) {
 | 
						||
  if (str) {
 | 
						||
    var isDType = isDate(str)
 | 
						||
    if (isDType || (!format && /^[0-9]{11,15}$/.test(str))) {
 | 
						||
      return new Date(isDType ? helperGetDateTime(str) : staticParseInt(str))
 | 
						||
    }
 | 
						||
    if (isString(str)) {
 | 
						||
      var resMaps = format ? parseCustomRules(str, format) : parseDefaultRules(str)
 | 
						||
      if (resMaps.y) {
 | 
						||
        if (resMaps.M) {
 | 
						||
          resMaps.M = toParseNum(resMaps.M) - 1
 | 
						||
        }
 | 
						||
        if (resMaps.S) {
 | 
						||
          // 如果7位则是微秒,只精确到3位毫秒
 | 
						||
          resMaps.S = toParseMs(toParseNum(resMaps.S.substring(0, 3)))
 | 
						||
        }
 | 
						||
        if (resMaps.Z) {
 | 
						||
          return parseTimeZone(resMaps)
 | 
						||
        } else {
 | 
						||
          return new Date(resMaps.y, resMaps.M || 0, resMaps.d || 1, resMaps.H || 0, resMaps.m || 0, resMaps.s || 0, resMaps.S || 0)
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return new Date('')
 | 
						||
}
 | 
						||
 | 
						||
module.exports = toStringDate
 |