@opentiny/vue-search-box 0.1.1-alpha.1 → 0.1.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/README.zh-CN.md +28 -0
- package/dist/es/index.es.js +11 -3
- package/dist/es/index.vue.es2.js +11 -42
- package/dist/es/utils/en_US.es.js +37 -37
- package/dist/es/utils/zh_CN.es.js +1 -1
- package/dist/lib/index.cjs.js +10 -2
- package/dist/lib/index.vue.cjs2.js +83 -114
- package/dist/lib/utils/en_US.cjs.js +38 -38
- package/dist/lib/utils/zh_CN.cjs.js +2 -2
- package/dist/types/utils/en_US.d.ts +2 -1
- package/dist/types/utils/zh_CN.d.ts +2 -1
- package/package.json +24 -20
- package/__tests__/search-box.spec.ts +0 -0
- package/scripts/pre-release.cjs +0 -8
- package/src/composables/use-checkbox.ts +0 -90
- package/src/composables/use-custom.ts +0 -53
- package/src/composables/use-datepicker.ts +0 -90
- package/src/composables/use-dropdown.ts +0 -251
- package/src/composables/use-edit.ts +0 -119
- package/src/composables/use-init.ts +0 -69
- package/src/composables/use-match.ts +0 -193
- package/src/composables/use-num-range.ts +0 -86
- package/src/composables/use-placeholder.ts +0 -43
- package/src/composables/use-tag.ts +0 -54
- package/src/index.less +0 -376
- package/src/index.ts +0 -13
- package/src/index.type.ts +0 -192
- package/src/index.vue +0 -1138
- package/src/smb-theme.ts +0 -15
- package/src/theme.json +0 -135
- package/src/utils/clone.ts +0 -37
- package/src/utils/date.ts +0 -724
- package/src/utils/dropdown.ts +0 -27
- package/src/utils/en_US.ts +0 -41
- package/src/utils/index.ts +0 -11
- package/src/utils/tag.ts +0 -80
- package/src/utils/type.ts +0 -6
- package/src/utils/validate.ts +0 -234
- package/src/utils/zh_CN.ts +0 -41
- package/src/vars.less +0 -56
- package/vite.config.theme.ts +0 -20
- package/vite.config.ts +0 -60
package/src/utils/date.ts
DELETED
|
@@ -1,724 +0,0 @@
|
|
|
1
|
-
/* eslint-disable prefer-rest-params */
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (c) 2022 - present TinyVue Authors.
|
|
4
|
-
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
|
|
5
|
-
*
|
|
6
|
-
* Use of this source code is governed by an MIT-style license.
|
|
7
|
-
*
|
|
8
|
-
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
|
9
|
-
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
|
10
|
-
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* 填充字符串,根据填充模式参数,在字符串前面或后面补充字附到指定的长度。
|
|
15
|
-
*
|
|
16
|
-
* fillChar('1', 3) // "001"
|
|
17
|
-
* fillChar('1', 3, true) // "100"
|
|
18
|
-
* fillChar('1', 3, true, ' ') // "1 "
|
|
19
|
-
*
|
|
20
|
-
* @param {String} string 被填充的字符串
|
|
21
|
-
* @param {Number} length 填充到某个长度
|
|
22
|
-
* @param {Boolean} [append=false] 是否在后面填充,默认为在前面填充
|
|
23
|
-
* @param {String} [chr="0"] 填充的字符,默认为0
|
|
24
|
-
* @returns {String}
|
|
25
|
-
*/
|
|
26
|
-
export const fillChar = (string, length, append, chr = '0') => {
|
|
27
|
-
if (typeof string === 'string' && typeof chr === 'string' && isNumber(length)) {
|
|
28
|
-
let len = string.length - length
|
|
29
|
-
|
|
30
|
-
if (len > 0) {
|
|
31
|
-
return append ? string.substr(0, length) : string.substr(len, length)
|
|
32
|
-
} else {
|
|
33
|
-
const appendStr = []
|
|
34
|
-
len = Math.abs(len) / chr.length
|
|
35
|
-
|
|
36
|
-
for (; len > 0; len--) {
|
|
37
|
-
appendStr.push(chr)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const s = appendStr.join('')
|
|
41
|
-
|
|
42
|
-
return append ? string + s : s + string
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const toString = Object.prototype.toString
|
|
48
|
-
export const hasOwn = Object.prototype.hasOwnProperty
|
|
49
|
-
|
|
50
|
-
const getProto = Object.getPrototypeOf
|
|
51
|
-
const fnToString = hasOwn.toString
|
|
52
|
-
const ObjectFunctionString = fnToString.call(Object)
|
|
53
|
-
|
|
54
|
-
const class2type = {
|
|
55
|
-
'[object Error]': 'error',
|
|
56
|
-
'[object Object]': 'object',
|
|
57
|
-
'[object RegExp]': 'regExp',
|
|
58
|
-
'[object Date]': 'date',
|
|
59
|
-
'[object Array]': 'array',
|
|
60
|
-
'[object Function]': 'function',
|
|
61
|
-
'[object AsyncFunction]': 'asyncFunction',
|
|
62
|
-
'[object String]': 'string',
|
|
63
|
-
'[object Number]': 'number',
|
|
64
|
-
'[object Boolean]': 'boolean'
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** 判断是否为 null / undefined */
|
|
68
|
-
export const isNull = (x: any) => x === null || x === undefined
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* 返回 JavaScript 对象的类型。
|
|
72
|
-
*
|
|
73
|
-
* 如果对象是 undefined 或 null,则返回相应的'undefined'或'null'。
|
|
74
|
-
*
|
|
75
|
-
* 其他一切都将返回它的类型'object'。
|
|
76
|
-
*
|
|
77
|
-
* typeOf( undefined ) === 'undefined'
|
|
78
|
-
* typeOf() === 'undefined'
|
|
79
|
-
* typeOf( window.notDefined ) === 'undefined'
|
|
80
|
-
* typeOf( null ) === 'null'
|
|
81
|
-
* typeOf( true ) === 'boolean'
|
|
82
|
-
* typeOf( 3 ) === 'number'
|
|
83
|
-
* typeOf( "test" ) === 'string'
|
|
84
|
-
* typeOf( function (){} ) === 'function'
|
|
85
|
-
* typeOf( [] ) === 'array'
|
|
86
|
-
* typeOf( new Date() ) === 'date'
|
|
87
|
-
* typeOf( new Error() ) === 'error'
|
|
88
|
-
* typeOf( /test/ ) === 'regExp'
|
|
89
|
-
*
|
|
90
|
-
*/
|
|
91
|
-
export const typeOf: (obj: any) => string = (obj) =>
|
|
92
|
-
isNull(obj) ? String(obj) : class2type[toString.call(obj)] || 'object'
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* 判断对象是否为 object 类型。
|
|
96
|
-
*
|
|
97
|
-
* isObject({}) // true
|
|
98
|
-
*/
|
|
99
|
-
export const isObject = (obj: any) => typeOf(obj) === 'object'
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* 判断对象是否为 function 类型。
|
|
103
|
-
*
|
|
104
|
-
* isObject(function (){) // true
|
|
105
|
-
|
|
106
|
-
*/
|
|
107
|
-
export const isFunction = (fn: any) => ['asyncFunction', 'function'].includes(typeOf(fn))
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* 判断对象是否为简单对象。
|
|
111
|
-
*
|
|
112
|
-
* 即不是 HTML 节点对象,也不是 window 对象,而是纯粹的对象(通过 '{}' 或者 'new Object' 创建的)。
|
|
113
|
-
*
|
|
114
|
-
* let obj = {}
|
|
115
|
-
* isPlainObject(obj) //true
|
|
116
|
-
*/
|
|
117
|
-
export const isPlainObject = (obj: any) => {
|
|
118
|
-
if (!obj || toString.call(obj) !== '[object Object]') {
|
|
119
|
-
return false
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const proto = getProto(obj)
|
|
123
|
-
if (!proto) {
|
|
124
|
-
return true
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const Ctor = hasOwn.call(proto, 'constructor') && proto.constructor
|
|
128
|
-
return typeof Ctor === 'function' && fnToString.call(Ctor) === ObjectFunctionString
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* 检查对象是否为空(不包含任何属性)。
|
|
133
|
-
*
|
|
134
|
-
* let obj = {}
|
|
135
|
-
* isEmptyObject(obj) // true
|
|
136
|
-
*/
|
|
137
|
-
export const isEmptyObject = (obj: any) => {
|
|
138
|
-
const type = typeOf(obj)
|
|
139
|
-
|
|
140
|
-
if (type === 'object' || type === 'array') {
|
|
141
|
-
for (const name in obj) {
|
|
142
|
-
if (hasOwn.call(obj, name)) {
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return true
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* 判断对象是否为数字类型。
|
|
153
|
-
*
|
|
154
|
-
* isNumber(369) // true
|
|
155
|
-
*/
|
|
156
|
-
export const isNumber = (value: any) => typeof value === 'number' && isFinite(value)
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 判断对象是否代表一个数值。
|
|
160
|
-
*
|
|
161
|
-
* isNumeric('-10') // true
|
|
162
|
-
* isNumeric(16) // true
|
|
163
|
-
* isNumeric(0xFF) // true
|
|
164
|
-
* isNumeric('0xFF') // true
|
|
165
|
-
* isNumeric('8e5') // true
|
|
166
|
-
* isNumeric(3.1415) // true
|
|
167
|
-
* isNumeric(+10) // true
|
|
168
|
-
* isNumeric('') // false
|
|
169
|
-
* isNumeric({}) // false
|
|
170
|
-
* isNumeric(NaN) // false
|
|
171
|
-
* isNumeric(null) // false
|
|
172
|
-
* isNumeric(true) // false
|
|
173
|
-
* isNumeric(Infinity) // false
|
|
174
|
-
* isNumeric(undefined) // false
|
|
175
|
-
*/
|
|
176
|
-
export const isNumeric = (value: any) => value - parseFloat(value) >= 0
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* 判断对象是否为日期类型。
|
|
180
|
-
*
|
|
181
|
-
* let date = new Date()
|
|
182
|
-
* isDate(date) // true
|
|
183
|
-
*/
|
|
184
|
-
export const isDate = (value) => typeOf(value) === 'date'
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* 判断两个值是否值相同且类型相同。
|
|
188
|
-
*
|
|
189
|
-
* 注:在 JavaScript 里 NaN === NaN 为 false,因此不能简单的用 === 来判断。
|
|
190
|
-
*
|
|
191
|
-
* isSame(1, 1) // true
|
|
192
|
-
* isSame(NaN, NaN) // true
|
|
193
|
-
*/
|
|
194
|
-
export const isSame = (x: any, y: any) =>
|
|
195
|
-
x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y))
|
|
196
|
-
|
|
197
|
-
/** 判断是否是正则表达式 */
|
|
198
|
-
export const isRegExp = (value: any) => typeOf(value) === 'regExp'
|
|
199
|
-
|
|
200
|
-
export const isPromise = (val) => isObject(val) && isFunction(val.then) && isFunction(val.catch)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
204
|
-
const yyyymmddReg = new RegExp(
|
|
205
|
-
'^(\\d{4})(/|-)(((0)?[1-9])|(1[0-2]))((/|-)(((0)?[1-9])|([1-2][0-9])|(3[0-1])))' +
|
|
206
|
-
'?( ((0)?[0-9]|1[0-9]|20|21|22|23):([0-5]?[0-9])((:([0-5]?[0-9]))?(.([0-9]{1,6}))?)?)?$'
|
|
207
|
-
)
|
|
208
|
-
const mmddyyyyReg = new RegExp(
|
|
209
|
-
'^(((0)?[1-9])|(1[0-2]))(/|-)(((0)?[1-9])|([1-2][0-9])|(3[0-1]))?(/|-)?(\\d{4})' +
|
|
210
|
-
'( ((0)?[0-9]|1[0-9]|20|21|22|23):([0-5]?[0-9])((:([0-5]?[0-9]))?(.([0-9]{1,6}))?)?)?$'
|
|
211
|
-
)
|
|
212
|
-
const iso8601Reg = new RegExp(
|
|
213
|
-
'^(\\d{4})-(((0)?[1-9])|(1[0-2]))-(((0)?[1-9])|([1-2][0-9])|(3[0-1]))T' +
|
|
214
|
-
'(((0)?[0-9]|1[0-9]|20|21|22|23):([0-5]?[0-9])((:([0-5]?[0-9]))?(.([0-9]{1,6}))?)?)?(Z|([+-])' +
|
|
215
|
-
'((0)?[0-9]|1[0-9]|20|21|22|23):?([0-5]?[0-9]))$'
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
const dateFormatRegs = {
|
|
219
|
-
'y{1,4}': /y{1,4}/,
|
|
220
|
-
'M{1,2}': /M{1,2}/,
|
|
221
|
-
'd{1,2}': /d{1,2}/,
|
|
222
|
-
'h{1,2}': /h{1,2}/,
|
|
223
|
-
'H{1,2}': /H{1,2}/,
|
|
224
|
-
'm{1,2}': /m{1,2}/,
|
|
225
|
-
's{1,2}': /s{1,2}/,
|
|
226
|
-
'S{1,3}': /S{1,3}/,
|
|
227
|
-
'Z{1,1}': /Z{1,1}/
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const maxDateValues = {
|
|
231
|
-
YEAR: 9999,
|
|
232
|
-
MONTH: 11,
|
|
233
|
-
DATE: 31,
|
|
234
|
-
HOUR: 23,
|
|
235
|
-
MINUTE: 59,
|
|
236
|
-
SECOND: 59,
|
|
237
|
-
MILLISECOND: 999
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const timezone1 = '-12:00,-11:00,-10:00,-09:30,-08:00,-07:00,-06:00,-05:00,-04:30,-04:00,-03:30,-02:00,-01:00'
|
|
241
|
-
const timezone2 = '-00:00,+00:00,+01:00,+02:00,+03:00,+03:30,+04:00,+04:30,+05:00,+05:30,+05:45,+06:00'
|
|
242
|
-
const timezone3 = '+06:30,+07:00,+08:00,+09:00,+10:00,+10:30,+11:00,+11:30,+12:00,+12:45,+13:00,+14:00'
|
|
243
|
-
const timezones = [].concat(timezone1.split(','), timezone2.split(','), timezone3.split(','))
|
|
244
|
-
|
|
245
|
-
const getTimezone = (date) => {
|
|
246
|
-
const timezoneoffset = 0 - date.getTimezoneOffset() / 60
|
|
247
|
-
let timezone
|
|
248
|
-
|
|
249
|
-
if (timezoneoffset === 0) {
|
|
250
|
-
timezone = 'Z'
|
|
251
|
-
} else if (timezoneoffset > 0) {
|
|
252
|
-
timezone = '+' + (timezoneoffset > 10 ? timezoneoffset : '0' + timezoneoffset) + '00'
|
|
253
|
-
} else {
|
|
254
|
-
timezone = (timezoneoffset < -10 ? timezoneoffset : '-0' + -timezoneoffset) + '00'
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
return timezone
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* 判断年份是否为闰年。
|
|
262
|
-
*
|
|
263
|
-
* isLeapYear(2017) // false
|
|
264
|
-
* isLeapYear(2000) // true
|
|
265
|
-
*
|
|
266
|
-
* @param {Number} year 年份
|
|
267
|
-
* @returns {Boolean}
|
|
268
|
-
*/
|
|
269
|
-
export const isLeapYear = (year) => year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0)
|
|
270
|
-
|
|
271
|
-
const getMilliseconds = (milliseconds) =>
|
|
272
|
-
milliseconds > maxDateValues.MILLISECOND ? Number(String(milliseconds).substring(0, 3)) : milliseconds
|
|
273
|
-
|
|
274
|
-
const getDateFromData = ({ year, month, date, hours, minutes, seconds, milliseconds }) => {
|
|
275
|
-
let daysInMonth = daysInMonths[month]
|
|
276
|
-
|
|
277
|
-
if (isLeapYear(year) && month === 1) {
|
|
278
|
-
daysInMonth += 1
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
if (date <= daysInMonth) {
|
|
282
|
-
return new Date(year, month, date, hours, minutes, seconds, getMilliseconds(milliseconds))
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const yyyymmddDateParser = (m) => {
|
|
287
|
-
/* istanbul ignore else */
|
|
288
|
-
if (m.length === 23) {
|
|
289
|
-
const year = Number(m[1])
|
|
290
|
-
const month = m[3] - 1
|
|
291
|
-
const date = Number(m[9] || 1)
|
|
292
|
-
const hours = m[15] || 0
|
|
293
|
-
const minutes = m[17] || 0
|
|
294
|
-
const seconds = m[20] || 0
|
|
295
|
-
const milliseconds = m[22] || 0
|
|
296
|
-
|
|
297
|
-
return getDateFromData({
|
|
298
|
-
date,
|
|
299
|
-
year,
|
|
300
|
-
hours,
|
|
301
|
-
month,
|
|
302
|
-
seconds,
|
|
303
|
-
minutes,
|
|
304
|
-
milliseconds
|
|
305
|
-
})
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const mmddyyyyDateParser = (m) => {
|
|
310
|
-
/* istanbul ignore else */
|
|
311
|
-
if (m.length === 22) {
|
|
312
|
-
const year = Number(m[12])
|
|
313
|
-
const month = m[1] - 1
|
|
314
|
-
const date = Number(m[6] || 1)
|
|
315
|
-
const hours = m[14] || 0
|
|
316
|
-
const minutes = m[16] || 0
|
|
317
|
-
const seconds = m[19] || 0
|
|
318
|
-
const milliseconds = m[21] || 0
|
|
319
|
-
|
|
320
|
-
return getDateFromData({
|
|
321
|
-
year,
|
|
322
|
-
month,
|
|
323
|
-
date,
|
|
324
|
-
hours,
|
|
325
|
-
minutes,
|
|
326
|
-
seconds,
|
|
327
|
-
milliseconds
|
|
328
|
-
})
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const iso8601DateParser = (m) => {
|
|
333
|
-
if (m.length !== 25) {
|
|
334
|
-
return
|
|
335
|
-
}
|
|
336
|
-
const year = Number(m[1])
|
|
337
|
-
const month = m[2] - 1
|
|
338
|
-
const date = Number(m[6])
|
|
339
|
-
const offset = new Date(year, month, date).getTimezoneOffset()
|
|
340
|
-
const hours = m[12] || 0
|
|
341
|
-
const minutes = m[14] || 0
|
|
342
|
-
const seconds = m[17] || 0
|
|
343
|
-
const milliseconds = m[19] || 0
|
|
344
|
-
let timeZone = m[20]
|
|
345
|
-
const sign = m[21]
|
|
346
|
-
const offsetHours = m[22] || 0
|
|
347
|
-
const offsetMinutes = m[24] || 0
|
|
348
|
-
let daysInMonth = daysInMonths[month]
|
|
349
|
-
let actHours
|
|
350
|
-
let actMinutes
|
|
351
|
-
if (isLeapYear(year) && month === 1) {
|
|
352
|
-
daysInMonth += 1
|
|
353
|
-
}
|
|
354
|
-
if (date <= daysInMonth) {
|
|
355
|
-
if (timeZone === 'Z') {
|
|
356
|
-
actHours = hours - offset / 60
|
|
357
|
-
actMinutes = minutes
|
|
358
|
-
} else {
|
|
359
|
-
if (!timeZone.includes(':')) {
|
|
360
|
-
timeZone = timeZone.substr(0, 3) + ':' + timeZone.substr(3)
|
|
361
|
-
}
|
|
362
|
-
if (!timezones.includes(timeZone)) {
|
|
363
|
-
return
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
actHours = sign === '+' ? hours - offsetHours - offset / 60 : Number(hours) + Number(offsetHours) - offset / 60
|
|
367
|
-
actMinutes = sign === '+' ? minutes - offsetMinutes : Number(minutes) + Number(offsetMinutes)
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return new Date(year, month, date, actHours, actMinutes, seconds, getMilliseconds(milliseconds))
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
const dateParsers = [
|
|
375
|
-
[yyyymmddReg, yyyymmddDateParser],
|
|
376
|
-
[mmddyyyyReg, mmddyyyyDateParser],
|
|
377
|
-
[iso8601Reg, iso8601DateParser]
|
|
378
|
-
]
|
|
379
|
-
|
|
380
|
-
const parseDate = (str) => {
|
|
381
|
-
for (let i = 0, len = dateParsers.length; i < len; i++) {
|
|
382
|
-
const m = dateParsers[i][0].exec(str)
|
|
383
|
-
|
|
384
|
-
if (m && m.length > 0) {
|
|
385
|
-
return dateParsers[i][1](m)
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const matchDateArray = (arr, value, text) => {
|
|
391
|
-
if (text) {
|
|
392
|
-
switch (text) {
|
|
393
|
-
case 'yyyy':
|
|
394
|
-
case 'yy':
|
|
395
|
-
arr[0] = value
|
|
396
|
-
break
|
|
397
|
-
case 'M':
|
|
398
|
-
case 'MM':
|
|
399
|
-
arr[1] = value - 1
|
|
400
|
-
break
|
|
401
|
-
case 'd':
|
|
402
|
-
case 'dd':
|
|
403
|
-
arr[2] = value
|
|
404
|
-
break
|
|
405
|
-
case 'h':
|
|
406
|
-
case 'hh':
|
|
407
|
-
arr[3] = value
|
|
408
|
-
break
|
|
409
|
-
case 'm':
|
|
410
|
-
case 'mm':
|
|
411
|
-
arr[4] = value
|
|
412
|
-
break
|
|
413
|
-
case 's':
|
|
414
|
-
case 'ss':
|
|
415
|
-
arr[5] = value
|
|
416
|
-
break
|
|
417
|
-
case 'S':
|
|
418
|
-
case 'SS':
|
|
419
|
-
case 'SSS':
|
|
420
|
-
arr[6] = value
|
|
421
|
-
break
|
|
422
|
-
default:
|
|
423
|
-
break
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
const getDateArray = (str, dateFormat) => {
|
|
429
|
-
const arr = [0, -1, 0, 0, 0, 0]
|
|
430
|
-
|
|
431
|
-
if (str.length !== dateFormat.length) {
|
|
432
|
-
return arr
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
let valuePos = 0
|
|
436
|
-
let textPos = 0
|
|
437
|
-
|
|
438
|
-
for (let i = 0, len = str.length; i < len; i++) {
|
|
439
|
-
const charValue = str.substr(i, 1)
|
|
440
|
-
const notNum = isNaN(Number(charValue)) || charValue.trim() === ''
|
|
441
|
-
|
|
442
|
-
if ((notNum && charValue === dateFormat.substr(i, 1)) || i === len - 1) {
|
|
443
|
-
let value
|
|
444
|
-
let text
|
|
445
|
-
|
|
446
|
-
if (notNum) {
|
|
447
|
-
value = str.substring(valuePos, i)
|
|
448
|
-
valuePos = i + 1
|
|
449
|
-
const end = dateFormat.indexOf(charValue, textPos)
|
|
450
|
-
|
|
451
|
-
text = dateFormat.substring(textPos, end === -1 ? dateFormat.length : end)
|
|
452
|
-
|
|
453
|
-
textPos = end + 1
|
|
454
|
-
} else {
|
|
455
|
-
value = str.substring(valuePos, len)
|
|
456
|
-
text = dateFormat.substring(textPos, len)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (value.length === text.length || value) {
|
|
460
|
-
matchDateArray(arr, value, text)
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
return arr
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const invalideTime = (time, min, max) => isNaN(time) || time < min || time > max
|
|
469
|
-
|
|
470
|
-
const invalideValue = ({ year, month, date, hours, minutes, seconds, milliseconds }) =>
|
|
471
|
-
invalideTime(year, 0, maxDateValues.YEAR) ||
|
|
472
|
-
invalideTime(month, 0, maxDateValues.MONTH) ||
|
|
473
|
-
invalideTime(date, 0, maxDateValues.DATE) ||
|
|
474
|
-
invalideTime(hours, 0, maxDateValues.HOUR) ||
|
|
475
|
-
invalideTime(minutes, 0, maxDateValues.MINUTE) ||
|
|
476
|
-
invalideTime(seconds, 0, maxDateValues.SECOND) ||
|
|
477
|
-
invalideTime(milliseconds, 0, maxDateValues.MILLISECOND)
|
|
478
|
-
|
|
479
|
-
const innerParse = (value, dateFormat) => {
|
|
480
|
-
if (typeof dateFormat === 'string') {
|
|
481
|
-
const arr = getDateArray(value, dateFormat)
|
|
482
|
-
const year = Number(arr[0])
|
|
483
|
-
const month = Number(arr[1])
|
|
484
|
-
const date = Number(arr[2] || 1)
|
|
485
|
-
const hours = Number(arr[3] || 0)
|
|
486
|
-
const minutes = Number(arr[4] || 0)
|
|
487
|
-
const seconds = Number(arr[5] || 0)
|
|
488
|
-
const milliseconds = Number(arr[6] || 0)
|
|
489
|
-
|
|
490
|
-
if (
|
|
491
|
-
invalideValue({
|
|
492
|
-
year,
|
|
493
|
-
month,
|
|
494
|
-
date,
|
|
495
|
-
hours,
|
|
496
|
-
minutes,
|
|
497
|
-
seconds,
|
|
498
|
-
milliseconds
|
|
499
|
-
})
|
|
500
|
-
) {
|
|
501
|
-
return
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
return getDateFromData({
|
|
505
|
-
year,
|
|
506
|
-
date,
|
|
507
|
-
month,
|
|
508
|
-
minutes,
|
|
509
|
-
hours,
|
|
510
|
-
milliseconds,
|
|
511
|
-
seconds
|
|
512
|
-
})
|
|
513
|
-
} else {
|
|
514
|
-
return parseDate(value)
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* 将字符串或数字转换成 Date 类型。
|
|
520
|
-
*
|
|
521
|
-
* toDate('2008/02/02') // new Date(2008, 1, 2)
|
|
522
|
-
* toDate(Date.UTC(2008, 1, 2)) // new Date(Date.UTC(2008, 1, 2))
|
|
523
|
-
* toDate('2008/2/2', 'yyyy/M/d') // new Date(2008, 1, 2)
|
|
524
|
-
* toDate('2008/02') // new Date(2008, 1, 1)
|
|
525
|
-
* toDate('02/2008') // new Date(2008, 1, 1)
|
|
526
|
-
* toDate('2008-02-01T20:08+08:00') // new Date(Date.UTC(2008, 0, 31, 16))
|
|
527
|
-
* toDate('2008-02-01T04:08-08:00') // new Date(Date.UTC(2008, 1, 1, 8))
|
|
528
|
-
*
|
|
529
|
-
* @param {String|Number} value 日期类型字符串或数字
|
|
530
|
-
* @param {String} [dateFormat] 转换格式
|
|
531
|
-
*
|
|
532
|
-
* 当 value 为字符串类型时,如果不提供,则尽可能按常见格式去解析。
|
|
533
|
-
* 常见格式为 yyyy[/-]MM[/-]dd hh:mm:ss.SSS, MM[/-]dd [/-]yyyy hh:mm:ss.SSS 及 ISO8601 时间格式。
|
|
534
|
-
*
|
|
535
|
-
* 如果提供,则按具体格式严格匹配解析,并且年份必须为4位。
|
|
536
|
-
* - yyyy 代表年份
|
|
537
|
-
* - M 或 MM 代表1位或2位的月份
|
|
538
|
-
* - d 或 dd 代表1位或2位的天数
|
|
539
|
-
* - h 或 hh 代表24小时的1位或2位的小时
|
|
540
|
-
* - m 或 mm 代表1位或2位的分钟,
|
|
541
|
-
* - s 或 ss 代表1位或2位的秒
|
|
542
|
-
* - S 或 SS 或 SSS 代表1位或2位或3位的毫秒
|
|
543
|
-
*
|
|
544
|
-
* @param {String} [minDate] 最小时间,默认为 0001-01-01 00:00:00.000
|
|
545
|
-
* @returns {Date}
|
|
546
|
-
*/
|
|
547
|
-
export const toDate = (value, dateFormat, minDate) => {
|
|
548
|
-
let date
|
|
549
|
-
|
|
550
|
-
if (isNumber(value)) {
|
|
551
|
-
date = new Date(value)
|
|
552
|
-
} else if (typeof value === 'string') {
|
|
553
|
-
date = innerParse(value, dateFormat)
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
if (minDate) {
|
|
557
|
-
const min = (minDate && toDate(minDate)) || new Date(1, 1, 1, 0, 0, 0)
|
|
558
|
-
return date && date < min ? min : date
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
return date
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* 将 Date 实例转换成日期字符串。
|
|
566
|
-
* 当 date 为日期字符串时,如果只有2个参数,则第2个参数为格式化后的格式化字符串
|
|
567
|
-
* 如果有3个参数,则第2个参数为转换的格式化参数,第3个参数为格式化后的格式化参数
|
|
568
|
-
*
|
|
569
|
-
* let date = new Date(2014, 4, 4, 1, 2, 3, 4)
|
|
570
|
-
* format(date) // "2014/05/04 01:02:03"
|
|
571
|
-
* format(date, 'yyyy/MM/dd hh:mm:ss.SSS') // "2014/05/04 01:02:03.004"
|
|
572
|
-
* format(date, 'yyyy/MM/dd hh:mm:ss.SSSZ') // "2014/05/04 01:02:03.004+0800"
|
|
573
|
-
* format(date, 'yyyy年MM月dd日 hh时mm分ss秒SSS毫秒') // "2014年05月04日 01时02分03秒004毫秒"
|
|
574
|
-
* format('2008/01/02', 'yyyy/MM/dd hh:mm:ss.SSS') // "2008/02/02 00:00:00.000"
|
|
575
|
-
* format('2014/01/02/03/04/05/06', 'yyyy/MM/dd/hh/mm/ss', 'yyyy年MM月dd日 hh时mm分ss秒') // "2014年01月02日 03时04分05秒006毫秒"
|
|
576
|
-
*
|
|
577
|
-
* @param {Date|String} date Date 实例或日期字符串
|
|
578
|
-
* @param {String} [dateFormat='yyyy/MM/dd hh:mm:ss'] 转换格式
|
|
579
|
-
*
|
|
580
|
-
* 常见格式为 yyyy[/-]MM[/-]dd hh:mm:ss.SSS, MM[/-]dd [/-]yyyy hh:mm:ss.SSS 及 ISO8601 时间格式。
|
|
581
|
-
*
|
|
582
|
-
* 如果提供,则按具体格式严格匹配解析,并且年份必须为4位。
|
|
583
|
-
* - yyyy 代表年份
|
|
584
|
-
* - M 或 MM 代表1位或2位的月份
|
|
585
|
-
* - d 或 dd 代表1位或2位的天数
|
|
586
|
-
* - h 或 hh 代表24小时的1位或2位的小时
|
|
587
|
-
* - m 或 mm 代表1位或2位的分钟,
|
|
588
|
-
* - s 或 ss 代表1位或2位的秒
|
|
589
|
-
* - S 或 SS 或 SSS 代表1位或2位或3位的毫秒
|
|
590
|
-
*
|
|
591
|
-
* @returns {String}
|
|
592
|
-
*/
|
|
593
|
-
export const format = function (date, dateFormat = 'yyyy/MM/dd hh:mm:ss') {
|
|
594
|
-
if (isDate(date)) {
|
|
595
|
-
if (typeof dateFormat === 'string') {
|
|
596
|
-
const o = {
|
|
597
|
-
'y{1,4}': date.getFullYear(),
|
|
598
|
-
'M{1,2}': date.getMonth() + 1,
|
|
599
|
-
'd{1,2}': date.getDate(),
|
|
600
|
-
'h{1,2}': date.getHours(),
|
|
601
|
-
'H{1,2}': date.getHours(),
|
|
602
|
-
'm{1,2}': date.getMinutes(),
|
|
603
|
-
's{1,2}': date.getSeconds(),
|
|
604
|
-
'S{1,3}': date.getMilliseconds(),
|
|
605
|
-
'Z{1,1}': getTimezone(date)
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
Object.keys(o).forEach((k) => {
|
|
609
|
-
const m = dateFormat.match(dateFormatRegs[k])
|
|
610
|
-
|
|
611
|
-
if (k && m && m.length) {
|
|
612
|
-
dateFormat = dateFormat.replace(m[0], k === 'Z{1,1}' ? o[k] : fillChar(o[k].toString(), m[0].length))
|
|
613
|
-
}
|
|
614
|
-
})
|
|
615
|
-
|
|
616
|
-
return dateFormat
|
|
617
|
-
}
|
|
618
|
-
} else if (typeof date === 'string' && arguments.length >= 2) {
|
|
619
|
-
let afterFormat = dateFormat
|
|
620
|
-
|
|
621
|
-
if (arguments.length === 2) {
|
|
622
|
-
dateFormat = undefined
|
|
623
|
-
} else {
|
|
624
|
-
afterFormat = arguments[2]
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
const dateValue = toDate(date, dateFormat)
|
|
628
|
-
return dateValue ? format(dateValue, afterFormat) : ''
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
/**
|
|
633
|
-
* 将当前操作的时间变更时区,主要用于转换一个其他时区的时间。
|
|
634
|
-
*
|
|
635
|
-
* var date = new Date(2017, 0, 1)
|
|
636
|
-
* getDateWithNewTimezone(date, 0, -2)
|
|
637
|
-
*
|
|
638
|
-
* @param {Date} date Date 实例或日期字符串
|
|
639
|
-
* @param {Number} otz 原时区 -12~13
|
|
640
|
-
* @param {Number} ntz 目标时区 -12~13 默认为当前时区
|
|
641
|
-
* @param {Boolean} TimezoneOffset 时区偏移量
|
|
642
|
-
* @returns {Date}
|
|
643
|
-
*/
|
|
644
|
-
export const getDateWithNewTimezone = (date, otz, ntz, timezoneOffset = 0) => {
|
|
645
|
-
if (!isDate(date) || !isNumeric(otz) || !isNumeric(ntz) || !isNumeric(timezoneOffset)) {
|
|
646
|
-
return
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const otzOffset = -otz * 60
|
|
650
|
-
const ntzOffset = -ntz * 60
|
|
651
|
-
const dstOffeset = timezoneOffset * 60
|
|
652
|
-
const utc = date.getTime() + otzOffset * 60000
|
|
653
|
-
|
|
654
|
-
return new Date(utc - (ntzOffset - dstOffeset) * 60000)
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* 按时区将 Date 实例转换成字符串。
|
|
659
|
-
*
|
|
660
|
-
* toDateStr(new Date(2017, 0, 1, 12, 30), 'yyyy/MM/dd hh:mm', 3) // "2017/01/01 15:30"
|
|
661
|
-
* toDateStr('2008/01/02', 'yyyy/MM/dd hh:mm', 3) // "2008/01/02 03:00"
|
|
662
|
-
*
|
|
663
|
-
* @param {Date|String} date Date 实例或日期字符串
|
|
664
|
-
* @param {String} dateFormat 转换格式
|
|
665
|
-
* @param {Number} [timezone] 时区
|
|
666
|
-
* @returns {String}
|
|
667
|
-
*/
|
|
668
|
-
export const toDateStr = (date, dateFormat, timezone) => {
|
|
669
|
-
if (date && isNumeric(timezone)) {
|
|
670
|
-
timezone = parseFloat(parseFloat(timezone).toFixed(2))
|
|
671
|
-
|
|
672
|
-
date = getDateWithNewTimezone(isDate(date) ? date : new Date(toDate(date)), 0, timezone)
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
return format(date, dateFormat)
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
/**
|
|
679
|
-
* 获取日期所在周的第一天,默认周一为第一天(可扩展周日为第一天)。
|
|
680
|
-
*
|
|
681
|
-
* getWeekOfFirstDay() // 返回当前日期所在周的周一同一时间
|
|
682
|
-
* getWeekOfFirstDay(true) // 返回当前日期所在周的周日同一时间
|
|
683
|
-
* getWeekOfFirstDay(new Date(2019, 8, 5)) // new Date(2019, 8, 2)
|
|
684
|
-
* getWeekOfFirstDay(new Date(2019, 8, 5)), true) // new Date(2019, 8, 1)
|
|
685
|
-
*
|
|
686
|
-
* @param {Date} [date=new Date()] date 日期实例,默认当天
|
|
687
|
-
* @param {Boolean} [isSunFirst] 是否设置周日为第一天,非必填
|
|
688
|
-
* @returns {Date}
|
|
689
|
-
*/
|
|
690
|
-
export const getWeekOfFirstDay = (date, isSunFirst) => {
|
|
691
|
-
typeof date === 'boolean' && (isSunFirst = date)
|
|
692
|
-
isDate(date) || (date = new Date())
|
|
693
|
-
|
|
694
|
-
const day = date.getDay()
|
|
695
|
-
let dayOfMonth = date.getDate()
|
|
696
|
-
|
|
697
|
-
if (day === 0) {
|
|
698
|
-
!isSunFirst && (dayOfMonth -= 6)
|
|
699
|
-
} else {
|
|
700
|
-
dayOfMonth = dayOfMonth - day + (!isSunFirst && 1)
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
return new Date(date.getFullYear(), date.getMonth(), dayOfMonth)
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
const TZRE = /(-|\+)(\d{2}):?(\d{2})$/
|
|
707
|
-
|
|
708
|
-
export const getLocalTimezone = () => 0 - new Date().getTimezoneOffset() / 60
|
|
709
|
-
|
|
710
|
-
export const getStrTimezone = (value) => {
|
|
711
|
-
const localTimeZone = getLocalTimezone()
|
|
712
|
-
const match = typeof value === 'string' && value.match(TZRE)
|
|
713
|
-
|
|
714
|
-
if (match) {
|
|
715
|
-
const minoffset = Number(match[2]) + Number(match[3]) / 60
|
|
716
|
-
value = minoffset * `${match[1]}1`
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
if (isNumber(value) && value >= -12 && value <= 12) {
|
|
720
|
-
return value
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
return localTimeZone
|
|
724
|
-
}
|