| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- /* Modified from https://github.com/taylorhakes/fecha
- * v4.1.0
- * hugh zhuang 把 YYYY-MM-DD 改成了 yyyy-MM-dd 与java后台 统一格式
- * YYYY修改为yyyy
- *
- * 备注:未支持多个国际化,该代码参考element-ui的日期帮助类
- * 增加日期格式处理
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Taylor Hakes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
- var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g
- var twoDigitsOptional = '[1-9]\\d?'
- var twoDigits = '\\d\\d'
- var threeDigits = '\\d{3}'
- var fourDigits = '\\d{4}'
- var word = '[^\\s]+'
- var literal = /\[([^]*?)\]/gm
- function shorten(arr, sLen) {
- var newArr = []
- for (var i = 0, len = arr.length; i < len; i++) {
- newArr.push(arr[i].substr(0, sLen))
- }
- return newArr
- }
- var monthUpdate = function(arrName) {
- return function(v, i18n) {
- var lowerCaseArr = i18n[arrName].map(function(v) { return v.toLowerCase() })
- var index = lowerCaseArr.indexOf(v.toLowerCase())
- if (index > -1) {
- return index
- }
- return null
- }
- }
- function assign(origObj) {
- var args = []
- for (var _i = 1; _i < arguments.length; _i++) {
- args[_i - 1] = arguments[_i]
- }
- for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
- var obj = args_1[_a]
- for (var key in obj) {
- // @ts-ignore ex
- origObj[key] = obj[key]
- }
- }
- return origObj
- }
- var dayNames = [
- 'Sunday',
- 'Monday',
- 'Tuesday',
- 'Wednesday',
- 'Thursday',
- 'Friday',
- 'Saturday'
- ]
- var monthNames = [
- 'January',
- 'February',
- 'March',
- 'April',
- 'May',
- 'June',
- 'July',
- 'August',
- 'September',
- 'October',
- 'November',
- 'December'
- ]
- var monthNamesShort = shorten(monthNames, 3)
- var dayNamesShort = shorten(dayNames, 3)
- var defaultI18n = {
- dayNamesShort: dayNamesShort,
- dayNames: dayNames,
- monthNamesShort: monthNamesShort,
- monthNames: monthNames,
- amPm: ['am', 'pm'],
- DoFn: function(dayOfMonth) {
- return (dayOfMonth +
- ['th', 'st', 'nd', 'rd'][dayOfMonth % 10 > 3
- ? 0
- : ((dayOfMonth - (dayOfMonth % 10) !== 10 ? 1 : 0) * dayOfMonth) % 10])
- }
- }
- var globalI18n = assign({}, defaultI18n)
- var setGlobalDateI18n = function(i18n) {
- return (globalI18n = assign(globalI18n, i18n))
- }
- var regexEscape = function(str) {
- return str.replace(/[|\\{()[^$+*?.-]/g, '\\$&')
- }
- var pad = function(val, len) {
- if (len === void 0) { len = 2 }
- val = String(val)
- while (val.length < len) {
- val = '0' + val
- }
- return val
- }
- var formatFlags = {
- d: function(dateObj) { return String(dateObj.getDate()) }, // zxh D 修改为 d
- dd: function(dateObj) { return pad(dateObj.getDate()) }, // zxh DD 修改为 dd
- do: function(dateObj, i18n) { // zxh Do 修改为 do
- return i18n.DoFn(dateObj.getDate())
- },
- D: function(dateObj) { return String(dateObj.getDay()) }, // zxh d 修改为D
- DD: function(dateObj) { return pad(dateObj.getDay()) }, // zxh dd 修改为 DD
- DDD: function(dateObj, i18n) { // zxh ddd 修改为 DDD
- return i18n.dayNamesShort[dateObj.getDay()]
- },
- DDDD: function(dateObj, i18n) { // zxh dddd 修改为 DDDD
- return i18n.dayNames[dateObj.getDay()]
- },
- M: function(dateObj) { return String(dateObj.getMonth() + 1) },
- MM: function(dateObj) { return pad(dateObj.getMonth() + 1) },
- MMM: function(dateObj, i18n) {
- return i18n.monthNamesShort[dateObj.getMonth()]
- },
- MMMM: function(dateObj, i18n) {
- return i18n.monthNames[dateObj.getMonth()]
- },
- yy: function(dateObj) { // zxh 修改 YY 修改为 yy
- return pad(String(dateObj.getFullYear()), 4).substr(2)
- },
- yyyy: function(dateObj) { return pad(dateObj.getFullYear(), 4) }, // zxh 修改 YYYY 修改为 yyyy
- h: function(dateObj) { return String(dateObj.getHours() % 12 || 12) },
- hh: function(dateObj) { return pad(dateObj.getHours() % 12 || 12) },
- H: function(dateObj) { return String(dateObj.getHours()) },
- HH: function(dateObj) { return pad(dateObj.getHours()) },
- m: function(dateObj) { return String(dateObj.getMinutes()) },
- mm: function(dateObj) { return pad(dateObj.getMinutes()) },
- s: function(dateObj) { return String(dateObj.getSeconds()) },
- ss: function(dateObj) { return pad(dateObj.getSeconds()) },
- S: function(dateObj) {
- return String(Math.round(dateObj.getMilliseconds() / 100))
- },
- SS: function(dateObj) {
- return pad(Math.round(dateObj.getMilliseconds() / 10), 2)
- },
- SSS: function(dateObj) { return pad(dateObj.getMilliseconds(), 3) },
- a: function(dateObj, i18n) {
- return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]
- },
- A: function(dateObj, i18n) {
- return dateObj.getHours() < 12
- ? i18n.amPm[0].toUpperCase()
- : i18n.amPm[1].toUpperCase()
- },
- ZZ: function(dateObj) {
- var offset = dateObj.getTimezoneOffset()
- return ((offset > 0 ? '-' : '+') +
- pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4))
- },
- Z: function(dateObj) {
- var offset = dateObj.getTimezoneOffset()
- return ((offset > 0 ? '-' : '+') +
- pad(Math.floor(Math.abs(offset) / 60), 2) +
- ':' +
- pad(Math.abs(offset) % 60, 2))
- }
- }
- var monthParse = function(v) { return +v - 1 }
- var emptyDigits = [null, twoDigitsOptional]
- var emptyWord = [null, word]
- var amPm = [
- 'isPm',
- word,
- function(v, i18n) {
- var val = v.toLowerCase()
- if (val === i18n.amPm[0]) {
- return 0
- } else if (val === i18n.amPm[1]) {
- return 1
- }
- return null
- }
- ]
- var timezoneOffset = [
- 'timezoneOffset',
- '[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z?',
- function(v) {
- var parts = (v + '').match(/([+-]|\d\d)/gi)
- if (parts) {
- var minutes = +parts[1] * 60 + parseInt(parts[2], 10)
- return parts[0] === '+' ? minutes : -minutes
- }
- return 0
- }
- ]
- var parseFlags = {
- d: ['day', twoDigitsOptional], // zxh D 修改为 d
- dd: ['day', twoDigits], // zxh DD 修改为 dd
- do: ['day', twoDigitsOptional + word, function(v) { return parseInt(v, 10) }], // zxh D0 修改为 do
- M: ['month', twoDigitsOptional, monthParse],
- MM: ['month', twoDigits, monthParse],
- YY: [
- 'year',
- twoDigits,
- function(v) {
- var now = new Date()
- var cent = +('' + now.getFullYear()).substr(0, 2)
- return +('' + (+v > 68 ? cent - 1 : cent) + v)
- }
- ],
- h: ['hour', twoDigitsOptional, undefined, 'isPm'],
- hh: ['hour', twoDigits, undefined, 'isPm'],
- H: ['hour', twoDigitsOptional],
- HH: ['hour', twoDigits],
- m: ['minute', twoDigitsOptional],
- mm: ['minute', twoDigits],
- s: ['second', twoDigitsOptional],
- ss: ['second', twoDigits],
- yyyy: ['year', fourDigits], // zxh YYYY修改为yyyy
- S: ['millisecond', '\\d', function(v) { return +v * 100 }],
- SS: ['millisecond', twoDigits, function(v) { return +v * 10 }],
- SSS: ['millisecond', threeDigits],
- D: emptyDigits, // zxh d 修改为 D
- DD: emptyDigits, // zxh dd 修改为 DD
- DDD: emptyWord,
- DDDD: emptyWord,
- MMM: ['month', word, monthUpdate('monthNamesShort')],
- MMMM: ['month', word, monthUpdate('monthNames')],
- a: amPm,
- A: amPm,
- ZZ: timezoneOffset,
- Z: timezoneOffset
- }
- // Some common format strings
- var globalMasks = {
- default: 'yyyy-MM-dd HH:mm:ss',
- shortDate: 'M/d/yy',
- mediumDate: 'MMM D, yyyy',
- longDate: 'MMMM d, yyyy',
- fullDate: 'DDDD, MMMM d, yyyy',
- isoDate: 'yyyy-MM-dd',
- isoDateTime: 'yyyy-MM-ddTHH:mm:ssZ',
- shortTime: 'HH:mm',
- mediumTime: 'HH:mm:ss',
- longTime: 'HH:mm:ss.SSS'
- }
- var setGlobalDateMasks = function(masks) { return assign(globalMasks, masks) }
- /** *
- * Format a date
- * @method format
- * @param {Date|number} dateObj
- * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
- * @returns {string} Formatted date string
- */
- var format = function(dateObj, mask, i18n) {
- if (dateObj === null || dateObj === undefined) return ''
- if (mask === void 0) { mask = globalMasks['default'] }
- if (i18n === void 0) { i18n = {} }
- if (typeof dateObj === 'number') {
- dateObj = new Date(dateObj)
- }
- if (Object.prototype.toString.call(dateObj) !== '[object Date]' ||
- isNaN(dateObj.getTime())) {
- throw new Error('Invalid Date pass to format')
- }
- mask = globalMasks[mask] || mask
- var literals = []
- // Make literals inactive by replacing them with @@@
- mask = mask.replace(literal, function($0, $1) {
- literals.push($1)
- return '@@@'
- })
- var combinedI18nSettings = assign(assign({}, globalI18n), i18n)
- // Apply formatting rules
- mask = mask.replace(token, function($0) {
- return formatFlags[$0](dateObj, combinedI18nSettings)
- })
- // Inline literal values back into the formatted value
- return mask.replace(/@@@/g, function() { return literals.shift() })
- }
- /**
- * Parse a date string into a Javascript Date object /
- * @method parse
- * @param {string} dateStr Date string
- * @param {string} format Date parse format
- * @param {i18n} I18nSettingsOptional Full or subset of I18N settings
- * @returns {Date|null} Returns Date object. Returns null what date string is invalid or doesn't match format
- */
- function parse(dateStr, format, i18n) {
- if (dateStr === null || dateStr === undefined) return ''
- if (i18n === void 0) { i18n = {} }
- if (typeof format !== 'string') {
- throw new Error('Invalid format in fecha parse')
- }
- // Check to see if the format is actually a mask
- format = globalMasks[format] || format
- // Avoid regular expression denial of service, fail early for really long strings
- // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
- if (dateStr.length > 1000) {
- return null
- }
- // Default to the beginning of the year.
- var today = new Date()
- var dateInfo = {
- year: today.getFullYear(),
- month: 0,
- day: 1,
- hour: 0,
- minute: 0,
- second: 0,
- millisecond: 0,
- isPm: null,
- timezoneOffset: null
- }
- var parseInfo = []
- var literals = []
- // Replace all the literals with @@@. Hopefully a string that won't exist in the format
- var newFormat = format.replace(literal, function($0, $1) {
- literals.push(regexEscape($1))
- return '@@@'
- })
- var specifiedFields = {}
- var requiredFields = {}
- // Change every token that we find into the correct regex
- newFormat = regexEscape(newFormat).replace(token, function($0) {
- var info = parseFlags[$0]
- var field = info[0]; var regex = info[1]; var requiredField = info[3]
- // Check if the person has specified the same field twice. This will lead to confusing results.
- if (specifiedFields[field]) {
- throw new Error('Invalid format. ' + field + ' specified twice in format')
- }
- specifiedFields[field] = true
- // Check if there are any required fields. For instance, 12 hour time requires AM/PM specified
- if (requiredField) {
- requiredFields[requiredField] = true
- }
- parseInfo.push(info)
- return '(' + regex + ')'
- })
- // Check all the required fields are present
- Object.keys(requiredFields).forEach(function(field) {
- if (!specifiedFields[field]) {
- throw new Error('Invalid format. ' + field + ' is required in specified format')
- }
- })
- // Add back all the literals after
- newFormat = newFormat.replace(/@@@/g, function() { return literals.shift() })
- // Check if the date string matches the format. If it doesn't return null
- var matches = dateStr.match(new RegExp(newFormat, 'i'))
- if (!matches) {
- return null
- }
- var combinedI18nSettings = assign(assign({}, globalI18n), i18n)
- // For each match, call the parser function for that date part
- for (var i = 1; i < matches.length; i++) {
- var _a = parseInfo[i - 1]; var field = _a[0]; var parser = _a[2]
- var value = parser
- ? parser(matches[i], combinedI18nSettings)
- : +matches[i]
- // If the parser can't make sense of the value, return null
- if (value == null) {
- return null
- }
- dateInfo[field] = value
- }
- if (dateInfo.isPm === 1 && dateInfo.hour != null && +dateInfo.hour !== 12) {
- dateInfo.hour = +dateInfo.hour + 12
- } else if (dateInfo.isPm === 0 && +dateInfo.hour === 12) {
- dateInfo.hour = 0
- }
- var dateWithoutTZ = new Date(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute, dateInfo.second, dateInfo.millisecond)
- var validateFields = [
- ['month', 'getMonth'],
- ['day', 'getDate'],
- ['hour', 'getHours'],
- ['minute', 'getMinutes'],
- ['second', 'getSeconds']
- ]
- for (var j = 0, len = validateFields.length; j < len; j++) {
- // Check to make sure the date field is within the allowed range. Javascript dates allows values
- // outside the allowed range. If the values don't match the value was invalid
- if (specifiedFields[validateFields[j][0]] &&
- dateInfo[validateFields[j][0]] !== dateWithoutTZ[validateFields[j][1]]()) {
- return null
- }
- }
- if (dateInfo.timezoneOffset == null) {
- return dateWithoutTZ
- }
- return new Date(Date.UTC(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute - dateInfo.timezoneOffset, dateInfo.second, dateInfo.millisecond))
- }
- /**
- * 格式化当前时间
- */
- function formatDate(mask = globalMasks.default, i18nSettings) {
- return format(new Date(), mask, i18nSettings)
- }
- /**
- * 格式当前时间
- */
- function parseDate(mask = globalMasks.default, i18nSettings) {
- return parse(formatDate(mask, i18nSettings), mask, i18nSettings)
- }
- /**
- * 相对时间字符串
- * @param {String|Number} time 时间格式字符串,或者时间
- * @returns {String} 相对时间字符串
- */
- function formatRelativeTime(time, mask = {}, i18nSettings) {
- if (!i18nSettings) {
- i18nSettings = function() {}
- }
- if (!time || time === null) return ''
- let date
- if (Object.prototype.toString.call(time) === '[object Date]') {
- date = time
- } else {
- date = !isNaN(time) ? new Date(time) : parse(time, mask['orig'] || globalMasks.default)
- }
- const timeStamp = date.getTime()
- // 获取当前时间时间戳
- const currentTime = (new Date()).getTime()
- // 判断传入时间戳是否早于当前时间戳
- const IS_EARLY = timeStamp <= currentTime
- // 获取两个时间戳差值
- let diff = currentTime - timeStamp
- // 如果IS_EARLY为false则差值取反
- if (!IS_EARLY) diff = -diff
- let resStr = ''
- const dirStr = IS_EARLY ? (i18nSettings('ibps.time.before') || '前') : (i18nSettings('ibps.time.after') || '后')
- if (diff < 1000) {
- resStr = i18nSettings('ibps.time.just') || '刚刚'
- } else if (diff < 60000) {
- // 少于等于59秒
- resStr = parseInt(diff / 1000) + (i18nSettings('ibps.time.seconds') || '秒') + dirStr
- } else if (diff >= 60000 && diff < 3600000) {
- // 多于59秒,少于等于59分钟59秒
- resStr = Math.floor(diff / 60000) + (i18nSettings('ibps.time.minutes') || '分钟') + dirStr
- } else if (diff >= 3600000 && diff < 86400000) {
- // 多于59分钟59秒,少于等于23小时59分钟59秒
- resStr = Math.floor(diff / 3600000) + (i18nSettings('ibps.time.hours') || '小时') + dirStr
- } else if (diff >= 86400000 && diff < 2623860000) {
- // 多于23小时59分钟59秒,少于等于29天59分钟59秒
- resStr = Math.floor(diff / 86400000) + (i18nSettings('ibps.time.days') || '天') + dirStr
- } else if (diff >= 2623860000 && diff <= 31567860000 && IS_EARLY) {
- // 多于29天59分钟59秒,少于364天23小时59分钟59秒,且传入的时间戳早于当前
- resStr = format(timeStamp, mask['day'] || 'MM-dd HH:mm')
- } else {
- resStr = format(timeStamp, mask['year'] || globalMasks.default)
- }
- return resStr
- }
- const dateDealFmt = {
- $dp: {
- has: {}
- },
- dealFmt: function(dateStr, dateFmt) {
- if (dateStr === '' || dateStr === null || dateStr === undefined) { return null }
- if (dateStr.length !== dateFmt.length) { // 格式化日期不相同
- const date = new Date(dateStr.replace(/-/g, '/'))
- if (!isNaN(date.getTime())) {
- return date
- } else { // IE
- const mydate = dateStr.slice(0, dateStr.indexOf('.'))// 去掉毫秒数
- return new Date(mydate.replace(/-/g, '/'))
- }
- }
- this.$dp.dateFmt = dateFmt
- this._setHas(/w/)
- this._setHas(/WW|W/)
- this._setHas(/DD|D/)
- this._setHas(/yyyy|yyy|yy|y/)
- this._setHas(/MMMM|MMM|MM|M/)
- this._setHas(/dd|d/)
- this._setHas(/HH|H/)
- this._setHas(/mm|m/)
- this._setHas(/ss|s/)
- const date = new Date()
- for (const p in this.$dp.has) {
- const has = this.$dp.has[p]
- if (has != null) {
- const val = parseInt(dateStr.substring(has.index, has.index + has[0].length), 10)
- if (p === 'y') { date.setYear(val) }
- if (p === 'M') { date.setMonth(val - 1, 1) }
- if (p === 'd') { date.setDate(val) }
- if (p === 'H') { date.setHours(val) }
- if (p === 'm') { date.setMinutes(val) }
- if (p === 's') { date.setSeconds(val) }
- }
- }
- return date
- },
- _setHas: function(re) {
- this.$dp.has[(re + '').slice(1, 2)] = re.exec(this.$dp.dateFmt)
- }
- }
- var fecha = {
- format: format,
- parse: parse,
- defaultI18n: defaultI18n,
- setGlobalDateI18n: setGlobalDateI18n,
- setGlobalDateMasks: setGlobalDateMasks,
- formatDate: formatDate,
- parseDate: parseDate,
- formatRelativeTime: formatRelativeTime
- }
- export default fecha
- export { assign, format, parse, defaultI18n, setGlobalDateI18n, setGlobalDateMasks, formatDate, parseDate, formatRelativeTime, dateDealFmt }
|