/** * 基本函数 * Create By GUY 2014\11\17 * */ import _ from "./1.lodash"; import { Widget } from "./4.widget"; import { createWidget } from "./5.inject"; import { prepares, _global } from "./0.foundation"; import { CRYPT_TYPE, aesDecrypt, aesEncrypt } from "./structure/aes"; import { Date as DateEnum, getMonthDays } from "./func/date"; const lodashFns = {}; function traverse(func, context) { return function (value, key, obj) { return func.call(context, key, value, obj); }; } function _apply(name) { return function () { return _[name](...arguments); }; } function _applyFunc(name) { return function () { const args = Array.prototype.slice.call(arguments, 0); args[1] = _.isFunction(args[1]) ? traverse(args[1], args[2]) : args[1]; return _[name](...args); }; } export function assert(v, is) { if (isFunction(is)) { if (!is(v)) { throw new Error(`${v} error`); } else { return true; } } if (!isArray(is)) { is = [is]; } if (!deepContains(is, v)) { throw new Error(`${v} error`); } return true; } export function warn(message) { console.warn(message); } export function UUID() { const f = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]; let str = ""; for (let i = 0; i < 16; i++) { const r = _global.parseInt(f.length * Math.random(), 10); str += f[r]; } return str; } export function isWidget(widget) { return widget instanceof Widget; } export function createWidgets(items, options, context) { if (!isArray(items)) { throw new Error("items must be array", items); } if (isWidget(options)) { context = options; options = {}; } else { options || (options = {}); } return map(flatten(items), (i, item) => createWidget(item, deepClone(options), context)); } export function createItems(data, innerAttr, outerAttr) { innerAttr = isArray(innerAttr) ? innerAttr : makeArray(flatten(data).length, innerAttr || {}); outerAttr = isArray(outerAttr) ? outerAttr : makeArray(flatten(data).length, outerAttr || {}); return map(data, (i, item) => { if (isArray(item)) { return createItems(item, innerAttr, outerAttr); } if (item instanceof Widget) { return extend({}, innerAttr.shift(), outerAttr.shift(), { type: null, el: item, }); } if (innerAttr[0] instanceof Widget) { outerAttr.shift(); return extend({}, item, { el: innerAttr.shift(), }); } if (item.el instanceof Widget) { innerAttr.shift(); return extend({}, outerAttr.shift(), { type: null }, item); } if (item.el) { return extend({}, outerAttr.shift(), item, { el: extend({}, innerAttr.shift(), item.el), }); } return extend({}, outerAttr.shift(), { el: extend({}, innerAttr.shift(), item), }); }); } // 用容器包装items export function packageItems(items, layouts) { for (let i = layouts.length - 1; i >= 0; i--) { items = map(items, (k, it) => extend({}, layouts[i], { items: [ extend({}, layouts[i].el, { el: it, }), ], }) ); } return items; } export function formatEL(obj) { if (obj && !obj.type && obj.el) { return obj; } return { el: obj, }; } // 剥开EL export function stripEL(obj) { return (obj.type && obj) || obj.el || obj; } export function trans2Element(widgets) { return map(widgets, (i, wi) => wi.element); } // 集合相关方法 _.each(["where", "findWhere", "invoke", "pluck", "shuffle", "sample", "toArray", "size"], name => { lodashFns[name] = _apply(name); }); _.each( [ "get", "set", "each", "map", "reduce", "reduceRight", "find", "filter", "reject", "every", "all", "some", "any", "max", "min", "sortBy", "groupBy", "indexBy", "countBy", "partition", "clamp", ], name => { if (name === "any") { lodashFns[name] = _applyFunc("some"); } else { lodashFns[name] = _applyFunc(name); } } ); export const where = lodashFns.where; export const findWhere = lodashFns.findWhere; export const invoke = lodashFns.invoke; export const pluck = lodashFns.pluck; export const shuffle = lodashFns.shuffle; export const sample = lodashFns.sample; export const toArray = lodashFns.toArray; export const size = lodashFns.size; export const get = lodashFns.get; export const set = lodashFns.set; export const each = lodashFns.each; export const map = lodashFns.map; export const reduce = lodashFns.reduce; export const reduceRight = lodashFns.reduceRight; export const find = lodashFns.find; export const filter = lodashFns.filter; export const reject = lodashFns.reject; export const every = lodashFns.every; export const all = lodashFns.all; export const some = lodashFns.some; export const any = lodashFns.any; export const max = lodashFns.max; export const min = lodashFns.min; export const sortBy = lodashFns.sortBy; export const groupBy = lodashFns.groupBy; export const indexBy = lodashFns.indexBy; export const countBy = lodashFns.countBy; export const partition = lodashFns.partition; export const clamp = lodashFns.clamp; // 数数 export function count(from, to, predicate) { let t; if (predicate) { for (t = from; t < to; t++) { predicate(t); } } return to - from; } // 倒数 export function inverse(from, to, predicate) { return count(to, from, predicate); } export function firstKey(obj) { let res = undefined; any(obj, (key, value) => { res = key; return true; }); return res; } export function lastKey(obj) { let res = undefined; each(obj, (key, value) => { res = key; return true; }); return res; } export function firstObject(obj) { let res = undefined; any(obj, (key, value) => { res = value; return true; }); return res; } export function lastObject(obj) { let res = undefined; each(obj, (key, value) => { res = value; return true; }); return res; } export function concat(obj1, obj2) { if (isKey(obj1)) { return map([].slice.apply(arguments), (idx, v) => v).join(""); } if (isArray(obj1)) { return _.concat.apply([], arguments); } if (isObject(obj1)) { return extend.apply({}, arguments); } } export function backEach(obj, predicate, context) { predicate = iteratee(predicate, context); for (let index = obj.length - 1; index >= 0; index--) { predicate(index, obj[index], obj); } return false; } export function backAny(obj, predicate, context) { predicate = iteratee(predicate, context); for (let index = obj.length - 1; index >= 0; index--) { if (predicate(index, obj[index], obj)) { return true; } } return false; } export function backEvery(obj, predicate, context) { predicate = iteratee(predicate, context); for (let index = obj.length - 1; index >= 0; index--) { if (!predicate(index, obj[index], obj)) { return false; } } return true; } export function backFindKey(obj, predicate, context) { predicate = iteratee(predicate, context); const objKeys = keys(obj); let key; for (let i = objKeys.length - 1; i >= 0; i--) { key = objKeys[i]; if (predicate(obj[key], key, obj)) { return key; } } } export function backFind(obj, predicate, context) { let key; if (isArray(obj)) { key = findLastIndex(obj, predicate, context); } else { key = backFindKey(obj, predicate, context); } if (key !== void 0 && key !== -1) { return obj[key]; } } export function remove(obj, target, context) { const targetIsFunction = isFunction(target); target = targetIsFunction || isArray(target) ? target : [target]; let i; if (isArray(obj)) { for (i = 0; i < obj.length; i++) { if ( (targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || (!targetIsFunction && contains(target, obj[i])) ) { obj.splice(i--, 1); } } } else { each(obj, (i, v) => { if ( (targetIsFunction && (target === obj[i] || target.apply(context, [i, obj[i]]) === true)) || (!targetIsFunction && contains(target, obj[i])) ) { delete obj[i]; } }); } } export function removeAt(obj, index) { index = isArray(index) ? index : [index]; const objIsArray = isArray(obj); let i; for (i = 0; i < index.length; i++) { if (objIsArray) { obj[index[i]] = "$deleteIndex"; } else { delete obj[index[i]]; } } if (objIsArray) { remove(obj, "$deleteIndex"); } } export function string2Array(str) { return str.split("&-&"); } export function array2String(array) { return array.join("&-&"); } export function abc2Int(string) { let idx = 0; const start = "A", str = string.toUpperCase(); for (let i = 0, len = str.length; i < len; ++i) { idx = str.charAt(i).charCodeAt(0) - start.charCodeAt(0) + 26 * idx + 1; if (idx > (2147483646 - str.charAt(i).charCodeAt(0) + start.charCodeAt(0)) / 26) { return 0; } } return idx; } export function int2Abc(num) { const DIGITS = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", ]; let idx = num, str = ""; if (num === 0) { return ""; } while (idx !== 0) { let t = idx % 26; if (t === 0) { t = 26; } str = DIGITS[t - 1] + str; idx = (idx - t) / 26; } return str; } // 数组相关的方法 _.each( [ "first", "initial", "last", "rest", "compact", "flatten", "without", "union", "intersection", "difference", "zip", "unzip", "object", "indexOf", "lastIndexOf", "sortedIndex", "range", "take", "takeRight", "uniqBy", "uniqWith" ], name => { lodashFns[name] = _apply(name); } ); _.each(["findIndex", "findLastIndex"], name => { lodashFns[name] = _applyFunc(name); }); export const first = lodashFns.first; export const initial = lodashFns.initial; export const last = lodashFns.last; export const rest = lodashFns.rest; export const compact = lodashFns.compact; export const flatten = lodashFns.flatten; export const without = lodashFns.without; export const union = lodashFns.union; export const intersection = lodashFns.intersection; export const difference = lodashFns.difference; export const zip = lodashFns.zip; export const unzip = lodashFns.unzip; export const object = lodashFns.object; export const indexOf = lodashFns.indexOf; export const lastIndexOf = lodashFns.lastIndexOf; export const sortedIndex = lodashFns.sortedIndex; export const range = lodashFns.range; export const take = lodashFns.take; export const takeRight = lodashFns.takeRight; export const uniqBy = lodashFns.uniqBy; export const uniqWith = lodashFns.uniqWith; export const findIndex = lodashFns.findIndex; export const findLastIndex = lodashFns.findLastIndex; // 构建一个长度为length的数组 export function makeArray(length, value) { const res = []; for (let i = 0; i < length; i++) { if (isNull(value)) { res.push(i); } else { res.push(deepClone(value)); } } return res; } export function makeObject(array, value) { const map = {}; for (let i = 0; i < array.length; i++) { if (isNull(value)) { map[array[i]] = array[i]; } else if (isFunction(value)) { map[array[i]] = value(i, array[i]); } else { map[array[i]] = deepClone(value); } } return map; } export function makeArrayByArray(array, value) { const res = []; if (!array) { return res; } for (let i = 0, len = array.length; i < len; i++) { if (isArray(array[i])) { res.push(makeArrayByArray(array[i], value)); } else { res.push(deepClone(value)); } } return res; } export function uniq(array, isSorted, iteratee, context) { if (array === null) { return []; } if (!isBoolean(isSorted)) { context = iteratee; iteratee = isSorted; isSorted = false; } iteratee && (iteratee = traverse(iteratee, context)); return _.uniq.call(_, array, isSorted, iteratee, context); } // 对象相关方法 _.each( [ "keys", "allKeys", "values", "pairs", "invert", "create", "functions", "extend", "extendOwn", "defaults", "clone", "property", "propertyOf", "matcher", "isEqual", "isMatch", "isEmpty", "isElement", "isNumber", "isString", "isArray", "isObject", "isPlainObject", "isArguments", "isFunction", "isFinite", "isBoolean", "isDate", "isRegExp", "isError", "isNaN", "isUndefined", "zipObject", "cloneDeep", "pickBy", ], name => { lodashFns[name] = _apply(name); } ); export const keys = lodashFns.keys; export const allKeys = lodashFns.allKeys; export const values = lodashFns.values; export const pairs = lodashFns.pairs; export const invert = lodashFns.invert; export const create = lodashFns.create; export const functions = lodashFns.functions; export const extend = lodashFns.extend; export const extendOwn = lodashFns.extendOwn; export const defaults = lodashFns.defaults; export const clone = lodashFns.clone; export const property = lodashFns.property; export const propertyOf = lodashFns.propertyOf; export const matcher = lodashFns.matcher; export const isEqual = lodashFns.isEqual; export const isMatch = lodashFns.isMatch; export const isEmpty = lodashFns.isEmpty; export const isElement = lodashFns.isElement; export const isNumber = lodashFns.isNumber; export const isString = lodashFns.isString; export const isArray = lodashFns.isArray; export const isObject = lodashFns.isObject; export const isPlainObject = lodashFns.isPlainObject; export const isArguments = lodashFns.isArguments; export const isFunction = lodashFns.isFunction; export const isFinite = lodashFns.isFinite; export const isBoolean = lodashFns.isBoolean; export const isDate = lodashFns.isDate; export const isRegExp = lodashFns.isRegExp; export const isError = lodashFns.isError; export const isNaN = lodashFns.isNaN; export const isUndefined = lodashFns.isUndefined; export const zipObject = lodashFns.zipObject; export const cloneDeep = lodashFns.cloneDeep; export const pickBy = lodashFns.pickBy; _.each(["mapObject", "findKey", "pick", "omit", "tap"], name => { lodashFns[name] = _applyFunc(name); }); export const mapObject = lodashFns.mapObject; export const findKey = lodashFns.findKey; export const pick = lodashFns.pick; export const omit = lodashFns.omit; export const tap = lodashFns.tap; export function inherit(sp, overrides) { function sb() { return sp.apply(this, arguments); } function F() {} const spp = sp.prototype; F.prototype = spp; sb.prototype = new F(); sb.superclass = spp; extend(sb.prototype, overrides, { superclass: sp, }); return sb; } export function init() { // 先把准备环境准备好 while (prepares && prepares.length > 0) { prepares.shift()(); } while (_global.___fineuiExposedFunction && _global.___fineuiExposedFunction.length > 0) { _global.___fineuiExposedFunction.shift()(); } if (_global.BI) { _global.BI.initialized = true; } } export function has(obj, keys) { if (isArray(keys)) { if (keys.length === 0) { return false; } return every(keys, (i, key) => _.has(obj, key)); } return _.has(...arguments); } export function freeze(value) { // 在ES5中,如果这个方法的参数不是一个对象(一个原始值),那么它会导致 TypeError // 在ES2015中,非对象参数将被视为要被冻结的普通对象,并被简单地返回 if (Object.freeze && isObject(value)) { return Object.freeze(value); } return value; } // 数字和字符串可以作为key export function isKey(key) { return isNumber(key) || (isString(key) && key.length > 0); } // 忽略大小写的等于 export function isCapitalEqual(a, b) { a = isNull(a) ? a : `${a}`.toLowerCase(); b = isNull(b) ? b : `${b}`.toLowerCase(); return isEqual(a, b); } export function isWidthOrHeight(w) { if (typeof w === "number") { return w >= 0; } else if (typeof w === "string") { return /^\d{1,3}(\.\d)?%$/.test(w) || w === "auto" || /^\d+(\.\d+)?px$/.test(w) || /^calc/.test(w); } } export function isNotNull(obj) { return !isNull(obj); } export function isNull(obj) { return typeof obj === "undefined" || obj === null; } export function isEmptyArray(arr) { return isArray(arr) && isEmpty(arr); } export function isNotEmptyArray(arr) { return isArray(arr) && !isEmpty(arr); } export function isEmptyObject(obj) { return isEqual(obj, {}); } export function isNotEmptyObject(obj) { return isPlainObject(obj) && !isEmptyObject(obj); } export function isWindow(obj) { return obj !== null && obj === obj.window; } export function isPromise(obj) { return !!obj && (isObject(obj) || isFunction(obj)) && isFunction(obj.then); } export const deepClone = _.cloneDeep; export const deepExtend = _.merge; export function isDeepMatch(object, attrs) { const attrsKeys = keys(attrs), length = attrsKeys.length; if (object === null) { return !length; } const obj = Object(object); for (let i = 0; i < length; i++) { const key = attrsKeys[i]; if (!isEqual(attrs[key], obj[key]) || !(key in obj)) { return false; } } return true; } export function contains(obj, target, fromIndex) { if (!_.isArrayLike(obj)) obj = values(obj); return indexOf(obj, target, typeof fromIndex === "number" && fromIndex) >= 0; } export function deepContains(obj, copy) { if (isObject(copy)) { return any(obj, (i, v) => isEqual(v, copy)); } return contains(obj, copy); } export function deepIndexOf(obj, target) { for (let i = 0; i < obj.length; i++) { if (isEqual(target, obj[i])) { return i; } } return -1; } export function deepRemove(obj, target) { let done = false; let i; if (isArray(obj)) { for (i = 0; i < obj.length; i++) { if (isEqual(target, obj[i])) { obj.splice(i--, 1); done = true; } } } else { each(obj, (i, v) => { if (isEqual(target, obj[i])) { delete obj[i]; done = true; } }); } return done; } export function deepWithout(obj, target) { if (isArray(obj)) { const result = []; for (let i = 0; i < obj.length; i++) { if (!isEqual(target, obj[i])) { result.push(obj[i]); } } return result; } const result = {}; each(obj, (i, v) => { if (!isEqual(target, obj[i])) { result[i] = v; } }); return result; } export function deepUnique(array) { const result = []; each(array, (i, item) => { if (!deepContains(result, item)) { result.push(item); } }); return result; } // 比较两个对象得出不一样的key值 export function deepDiff(object, other) { object || (object = {}); other || (other = {}); const result = []; const used = []; for (const b in object) { if (has(object, b)) { if (!isEqual(object[b], other[b])) { result.push(b); } used.push(b); } } for (const b in other) { if (has(other, b) && !contains(used, b)) { result.push(b); } } return result; } // 通用方法 _.each(["uniqueId", "result", "chain", "iteratee", "unescape", "before", "after", "chunk"], name => { lodashFns[name] = (...args) => _[name](...args); }); export const uniqueId = lodashFns.uniqueId; export const result = lodashFns.result; export const chain = lodashFns.chain; export const iteratee = lodashFns.iteratee; export const unescape = lodashFns.unescape; export const before = lodashFns.before; export const after = lodashFns.after; export const chunk = lodashFns.chunk; // 事件相关方法 _.each(["bind", "once", "partial", "debounce", "throttle", "delay", "defer", "wrap"], name => { lodashFns[name] = (...args) => _[name](...args); }); export const bind = lodashFns.bind; export const once = lodashFns.once; export const partial = lodashFns.partial; export const debounce = lodashFns.debounce; export const throttle = lodashFns.throttle; export const delay = lodashFns.delay; export const defer = lodashFns.defer; export const wrap = lodashFns.wrap; export let nextTick = /*!PURE*/(function () { const callbacks = []; let pending = false; let timerFunc = void 0; function nextTickHandler() { pending = false; const copies = callbacks.slice(0); callbacks.length = 0; for (let i = 0; i < copies.length; i++) { copies[i](); } } if (typeof Promise !== "undefined") { const p = Promise.resolve(); timerFunc = function timerFunc() { p.then(nextTickHandler); }; } else if (typeof MutationObserver !== "undefined") { let counter = 1; const observer = new MutationObserver(nextTickHandler); const textNode = document.createTextNode(String(counter)); observer.observe(textNode, { characterData: true, }); timerFunc = function timerFunc() { counter = (counter + 1) % 2; textNode.data = String(counter); }; } else if (typeof setImmediate !== "undefined") { timerFunc = function timerFunc() { setImmediate(nextTickHandler); }; } else { // Fallback to setTimeout. timerFunc = function timerFunc() { setTimeout(nextTickHandler, 0); }; } return function queueNextTick(cb) { let _resolve = void 0; const args = [].slice.call(arguments, 1); callbacks.push(() => { if (cb) { try { cb(...args); } catch (e) { console.error(e); } } else if (_resolve) { _resolve(...args); } }); if (!pending) { pending = true; timerFunc(); } if (!cb && typeof Promise !== "undefined") { return new Promise((resolve, reject) => { _resolve = resolve; }); } }; })(); export const setNextTick = (fn) => { nextTick = fn; } // 数字相关方法 _.each(["random"], name => { lodashFns[name] = _apply(name); }); export const random = lodashFns.random; export function parseInt(number) { let radix = 10; if (/^0x/g.test(number)) { radix = 16; } try { return _global.parseInt(number, radix); } catch (e) { throw new Error(`${number}parse int error`); } } export function parseSafeInt(value) { const MAX_SAFE_INTEGER = 9007199254740991; return value ? clamp(parseInt(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) : value === 0 ? value : 0; } export function parseFloat(number) { try { return _global.parseFloat(number); } catch (e) { throw new Error(`${number}parse float error`); } } export function isNaturalNumber(number) { return /^\d+$/.test(number); } export function isPositiveInteger(number) { return /^\+?[1-9][0-9]*$/.test(number); } export function isNegativeInteger(number) { return /^-[1-9][0-9]*$/.test(number); } export function isInteger(number) { return /^-?\d+$/.test(number); } export function isNumeric(number) { return !_global.isNaN(_global.parseFloat(number)) && _global.isFinite(number); } export function isFloat(number) { return /^([+-]?)\d*\.\d+$/.test(number); } export function isOdd(number) { if (!isInteger(number)) { return false; } return (number & 1) === 1; } export function isEven(number) { if (!isInteger(number)) { return false; } return (number & 1) === 0; } export function sum(array, iteratee, context) { let sum = 0; each(array, (i, item) => { if (iteratee) { sum += Number(iteratee.apply(context, [i, item])); } else { sum += Number(item); } }); return sum; } export function average(array, iteratee, context) { const sumResult = sum(array, iteratee, context); return sumResult / array.length; } export function trim(...args) { return _.trim(...args); } export function toUpperCase(string) { return `${string}`.toLocaleUpperCase(); } export function toLowerCase(string) { return `${string}`.toLocaleLowerCase(); } export function isEndWithBlank(string) { return /(\s|\u00A0)$/.test(string); } export function isLiteral(exp) { return /^\s?(true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/.test(exp); } export function stripQuotes(str) { const a = str.charCodeAt(0); const b = str.charCodeAt(str.length - 1); return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str; } // background-color => backgroundColor export function camelize(str) { return str.replace(/-(.)/g, (_, character) => character.toUpperCase()); } // backgroundColor => background-color export function hyphenate(str) { return str.replace(/([A-Z])/g, "-$1").toLowerCase(); } export function isNotEmptyString(str) { return isString(str) && !isEmpty(str); } export function isEmptyString(str) { return isString(str) && isEmpty(str); } /** * 通用解密方法 * @param type 解密方式 * @param text 文本 * @param key 种子 * @return {*} */ export function encrypt(type, text, key) { switch (type) { case CRYPT_TYPE.AES: default: return aesEncrypt(text, key); } } /** * 通用解密方法 * @param type 解密方式 * @param text 文本 * @param key 种子 * @return {*} */ export function decrypt(type, text, key) { switch (type) { case CRYPT_TYPE.AES: default: return aesDecrypt(text, key); } } /** * 对字符串中的'和\做编码处理 * @static * @param {String} string 要做编码处理的字符串 * @return {String} 编码后的字符串 */ export function escape(string) { return string.replace(/('|\\)/g, "\\$1"); } /** * 让字符串通过指定字符做补齐的函数 * * var s = BI.leftPad('123', 5, '0');//s的值为:'00123' * * @static * @param {String} val 原始值 * @param {Number} size 总共需要的位数 * @param {String} ch 用于补齐的字符 * @return {String} 补齐后的字符串 */ export function leftPad(val, size, ch) { let result = String(val); if (!ch) { ch = " "; } while (result.length < size) { result = ch + result; } return result.toString(); } /** * 对字符串做替换的函数 * * var cls = 'my-class', text = 'Some text'; * var res = BI.format('
{1}
', cls, text); * //res的值为:'
Some text
'; * * @static * @param {String} format 要做替换的字符串,替换字符串1,替换字符串2... * @return {String} 做了替换后的字符串 */ export function format(format) { const args = Array.prototype.slice.call(arguments, 1); return format.replace(/\{(\d+)\}/g, (m, i) => args[i]); } /** * 是否是闰年 * @param year * @returns {boolean} */ export function isLeapYear(year) { return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; } /** * 检测是否在有效期 * * @param YY 年 * @param MM 月 * @param DD 日 * @param minDate '1900-01-01' * @param maxDate '2099-12-31' * @returns {Array} 若无效返回无效状态,数组第一位为无效属性,第二位缺省为超下限,1为超上限 */ export function checkDateVoid(YY, MM, DD, minDate, maxDate) { let back = []; YY = YY | 0; MM = MM | 0; DD = DD | 0; minDate = isString(minDate) ? minDate.match(/\d+/g) : minDate; maxDate = isString(maxDate) ? maxDate.match(/\d+/g) : maxDate; if (YY < minDate[0]) { back = ["y"]; } else if (YY > maxDate[0]) { back = ["y", 1]; } else if (YY >= minDate[0] && YY <= maxDate[0]) { if (YY == minDate[0]) { if (MM < minDate[1]) { back = ["m"]; } else if (MM == minDate[1]) { if (DD < minDate[2]) { back = ["d"]; } } } if (YY == maxDate[0]) { if (MM > maxDate[1]) { back = ["m", 1]; } else if (MM == maxDate[1]) { if (DD > maxDate[2]) { back = ["d", 1]; } } } } return back; } export function checkDateLegal(str) { const ar = str.match(/\d+/g); const YY = ar[0] | 0, MM = ar[1] | 0, DD = ar[2] | 0; if (ar.length <= 1) { return true; } if (ar.length <= 2) { return MM >= 1 && MM <= 12; } const MD = DateEnum._MD.slice(0); MD[1] = isLeapYear(YY) ? 29 : 28; return MM >= 1 && MM <= 12 && DD <= MD[MM - 1]; } /** 解析日期时间字符串 * * @param str * @param fmt * @returns {Date|Date} * 年月日缺省值为当前日期, 时分秒缺省值为0 */ export function parseDateTime(str, fmt) { const today = getDate(); let y; let m; let d; // wei : 对于fmt为‘YYYYMM’或者‘YYYYMMdd’的格式,str的值为类似'201111'的形式,因为年月之间没有分隔符,所以正则表达式分割无效,导致bug7376。 const a = str.split(/\W+/); if (fmt.toLowerCase() === "%y%x" || fmt.toLowerCase() === "%y%x%d") { const yearlength = 4; const otherlength = 2; a[0] = str.substring(0, yearlength); a[1] = str.substring(yearlength, yearlength + otherlength); a[2] = str.substring(yearlength + otherlength, yearlength + otherlength * 2); } const b = fmt.match(/%./g); let i = 0, j = 0; let hr = 0; let min = 0; let sec = 0; for (i = 0; i < a.length; ++i) { switch (b[i]) { case "%d": case "%e": d = _global.parseInt(a[i], 10); break; case "%X": m = _global.parseInt(a[i], 10) - 1; break; case "%x": m = _global.parseInt(a[i], 10) - 1; break; case "%Y": case "%y": y = _global.parseInt(a[i], 10); y < 100 && (y += y > 29 ? 1900 : 2000); break; case "%b": case "%B": for (j = 0; j < 12; ++j) { if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) { m = j; break; } } break; case "%H": case "%I": case "%k": case "%l": hr = _global.parseInt(a[i], 10); break; case "%P": case "%p": if (/pm/i.test(a[i]) && hr < 12) { hr += 12; } else if (/am/i.test(a[i]) && hr >= 12) { hr -= 12; } break; case "%Q": case "%q": m = (_global.parseInt(a[i], 10) - 1) * 3; break; case "%M": min = _global.parseInt(a[i], 10); break; case "%S": sec = _global.parseInt(a[i], 10); break; default: } } // if (!a[i]) { // continue; // } if (_global.isNaN(y)) { y = today.getFullYear(); } if (_global.isNaN(m)) { m = today.getMonth(); } if (_global.isNaN(d)) { d = 1; } if (_global.isNaN(hr)) { hr = today.getHours(); } if (_global.isNaN(min)) { min = today.getMinutes(); } if (_global.isNaN(sec)) { sec = today.getSeconds(); } if (y !== 0) { return getDate(y, m, d, hr, min, sec); } y = 0; m = -1; d = 0; for (i = 0; i < a.length; ++i) { if (a[i].search(/[a-zA-Z]+/) !== -1) { let t = -1; for (j = 0; j < 12; ++j) { if (BI.getMonthName(j).substr(0, a[i].length).toLowerCase() === a[i].toLowerCase()) { t = j; break; } } if (t !== -1) { if (m !== -1) { d = m + 1; } m = t; } } else if (_global.parseInt(a[i], 10) <= 12 && m === -1) { m = a[i] - 1; } else if (_global.parseInt(a[i], 10) > 31 && y === 0) { y = _global.parseInt(a[i], 10); y < 100 && (y += y > 29 ? 1900 : 2000); } else if (d === 0) { d = a[i]; } } if (y === 0) { y = today.getFullYear(); } if (m === -1) { m = today.getMonth(); } if (m !== -1 && d !== 0) { return getDate(y, m, d, hr, min, sec); } return today; } export function getDate(...args) { const length = args.length; let dt; switch (length) { // new Date() case 0: dt = new Date(); break; // new Date(long) case 1: dt = new Date(args[0]); break; // new Date(year, month) case 2: dt = new Date(args[0], args[1]); break; // new Date(year, month, day) case 3: dt = new Date(args[0], args[1], args[2]); break; // new Date(year, month, day, hour) case 4: dt = new Date(args[0], args[1], args[2], args[3]); break; // new Date(year, month, day, hour, minute) case 5: dt = new Date(args[0], args[1], args[2], args[3], args[4]); break; // new Date(year, month, day, hour, minute, second) case 6: dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); break; // new Date(year, month, day, hour, minute, second, millisecond) case 7: dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; default: dt = new Date(); break; } if (isNotNull(BI.timeZone) && (arguments.length === 0 || (arguments.length === 1 && isNumber(arguments[0])))) { const localTime = dt.getTime(); // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 const localOffset = dt.getTimezoneOffset() * 60000; // 获得当地时间偏移的毫秒数 const utc = localTime + localOffset; // utc即GMT时间标准时区 return new Date(utc + BI.timeZone); // + Pool.timeZone.offset); } return dt; } export function getTime() { const length = arguments.length; const args = arguments; let dt; switch (length) { // new Date() case 0: dt = new Date(); break; // new Date(long) case 1: dt = new Date(args[0]); break; // new Date(year, month) case 2: dt = new Date(args[0], args[1]); break; // new Date(year, month, day) case 3: dt = new Date(args[0], args[1], args[2]); break; // new Date(year, month, day, hour) case 4: dt = new Date(args[0], args[1], args[2], args[3]); break; // new Date(year, month, day, hour, minute) case 5: dt = new Date(args[0], args[1], args[2], args[3], args[4]); break; // new Date(year, month, day, hour, minute, second) case 6: dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5]); break; // new Date(year, month, day, hour, minute, second, millisecond) case 7: dt = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; default: dt = new Date(); break; } if (isNotNull(BI.timeZone)) { // BI-33791 1901年以前的东8区标准是GMT+0805, 统一无论是什么时间,都以整的0800这样的为基准 return dt.getTime() + BI.timeZone + new Date().getTimezoneOffset() * 60000; } return dt.getTime(); }