@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.
Files changed (43) hide show
  1. package/README.md +28 -0
  2. package/README.zh-CN.md +28 -0
  3. package/dist/es/index.es.js +11 -3
  4. package/dist/es/index.vue.es2.js +11 -42
  5. package/dist/es/utils/en_US.es.js +37 -37
  6. package/dist/es/utils/zh_CN.es.js +1 -1
  7. package/dist/lib/index.cjs.js +10 -2
  8. package/dist/lib/index.vue.cjs2.js +83 -114
  9. package/dist/lib/utils/en_US.cjs.js +38 -38
  10. package/dist/lib/utils/zh_CN.cjs.js +2 -2
  11. package/dist/types/utils/en_US.d.ts +2 -1
  12. package/dist/types/utils/zh_CN.d.ts +2 -1
  13. package/package.json +24 -20
  14. package/__tests__/search-box.spec.ts +0 -0
  15. package/scripts/pre-release.cjs +0 -8
  16. package/src/composables/use-checkbox.ts +0 -90
  17. package/src/composables/use-custom.ts +0 -53
  18. package/src/composables/use-datepicker.ts +0 -90
  19. package/src/composables/use-dropdown.ts +0 -251
  20. package/src/composables/use-edit.ts +0 -119
  21. package/src/composables/use-init.ts +0 -69
  22. package/src/composables/use-match.ts +0 -193
  23. package/src/composables/use-num-range.ts +0 -86
  24. package/src/composables/use-placeholder.ts +0 -43
  25. package/src/composables/use-tag.ts +0 -54
  26. package/src/index.less +0 -376
  27. package/src/index.ts +0 -13
  28. package/src/index.type.ts +0 -192
  29. package/src/index.vue +0 -1138
  30. package/src/smb-theme.ts +0 -15
  31. package/src/theme.json +0 -135
  32. package/src/utils/clone.ts +0 -37
  33. package/src/utils/date.ts +0 -724
  34. package/src/utils/dropdown.ts +0 -27
  35. package/src/utils/en_US.ts +0 -41
  36. package/src/utils/index.ts +0 -11
  37. package/src/utils/tag.ts +0 -80
  38. package/src/utils/type.ts +0 -6
  39. package/src/utils/validate.ts +0 -234
  40. package/src/utils/zh_CN.ts +0 -41
  41. package/src/vars.less +0 -56
  42. package/vite.config.theme.ts +0 -20
  43. 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
- }