mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-04-06 03:58:05 +08:00
[impovement] datepicker 使用原生 picker-view 重写 (#294)
* feat: cell 自定义组件 * [new feature] DatetimePicker:新增时间选择组件 * fix: support picker view * improvement:支持 picker-view * fix: issue #286
This commit is contained in:
parent
82d1a8ae98
commit
d3eee374dd
@ -1,7 +1,16 @@
|
|||||||
Page({
|
Page({
|
||||||
|
onLoad () {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setData({
|
||||||
|
date: new Date('2300/12/12').getTime()
|
||||||
|
})
|
||||||
|
}, 100)
|
||||||
|
},
|
||||||
|
|
||||||
customChange ({detail}) {
|
customChange ({detail}) {
|
||||||
this.setData({pickerView1: detail.value.join('-')})
|
this.setData({pickerView1: detail.value.join('-')})
|
||||||
},
|
},
|
||||||
|
|
||||||
nativeChange ({detail}) {
|
nativeChange ({detail}) {
|
||||||
this.setData({pickerView2: detail.value.join('-')})
|
this.setData({pickerView2: detail.value.join('-')})
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,13 @@
|
|||||||
<zan-cell-group>
|
<zan-cell-group>
|
||||||
<zan-cell title="选择时间">
|
<zan-cell title="选择时间">
|
||||||
<zan-date-picker
|
<zan-date-picker
|
||||||
native
|
|
||||||
slot="footer"
|
slot="footer"
|
||||||
|
date="{{ date }}"
|
||||||
bindchange="change"
|
bindchange="change"
|
||||||
bindcancel="cancel"
|
bindcancel="cancel"
|
||||||
placeholder="原生 picker"
|
placeholder="异步初始值"
|
||||||
placeholder-class="my-customer-class-name" />
|
placeholder-class="my-customer-class-name"
|
||||||
</zan-cell>
|
/>
|
||||||
|
|
||||||
<zan-cell title="选择时间">
|
|
||||||
<zan-date-picker
|
|
||||||
slot="footer"
|
|
||||||
bindchange="change"
|
|
||||||
bindcancel="cancel"
|
|
||||||
placeholder="自定义 picker"
|
|
||||||
placeholder-class="my-customer-class-name" />
|
|
||||||
</zan-cell>
|
</zan-cell>
|
||||||
|
|
||||||
<zan-cell title="选择时间">
|
<zan-cell title="选择时间">
|
||||||
@ -27,7 +19,7 @@
|
|||||||
bindchange="change"
|
bindchange="change"
|
||||||
bindcancel="cancel"
|
bindcancel="cancel"
|
||||||
placeholder="只显示部分列的 picker"
|
placeholder="只显示部分列的 picker"
|
||||||
placeholder-class="my-customer-class-name" />
|
/>
|
||||||
</zan-cell>
|
</zan-cell>
|
||||||
|
|
||||||
<zan-cell title="选择时间">
|
<zan-cell title="选择时间">
|
||||||
@ -36,8 +28,8 @@
|
|||||||
bindchange="change"
|
bindchange="change"
|
||||||
bindcancel="cancel"
|
bindcancel="cancel"
|
||||||
placeholder="自定义显示格式的 picker"
|
placeholder="自定义显示格式的 picker"
|
||||||
format="选择的是YY-MM-DD HH:mm:ss"
|
format="选择的是YYYY-MM-DD HH:mm:ss"
|
||||||
placeholder-class="my-customer-class-name" />
|
/>
|
||||||
</zan-cell>
|
</zan-cell>
|
||||||
</zan-cell-group>
|
</zan-cell-group>
|
||||||
</zan-panel>
|
</zan-panel>
|
||||||
@ -49,20 +41,17 @@
|
|||||||
picker-view
|
picker-view
|
||||||
bindchange="customChange"
|
bindchange="customChange"
|
||||||
bindcancel="cancel"
|
bindcancel="cancel"
|
||||||
placeholder="自定义显示格式的 picker"
|
/>
|
||||||
format="选择的是YY-MM-DD HH:mm:ss"
|
|
||||||
placeholder-class="my-customer-class" />
|
|
||||||
</zan-panel>
|
</zan-panel>
|
||||||
|
|
||||||
<zan-panel class="picker-panel-demo">
|
<zan-panel class="picker-panel-demo">
|
||||||
<zan-cell title="选择时间" value="{{ pickerView2 || '原生组件'}}"></zan-cell>
|
<zan-cell title="选择时间" value="{{ pickerView2 || '只显示部分列'}}"></zan-cell>
|
||||||
<zan-date-picker
|
<zan-date-picker
|
||||||
native
|
picker-view
|
||||||
picker-view
|
|
||||||
bindchange="nativeChange"
|
bindchange="nativeChange"
|
||||||
bindcancel="cancel"
|
bindcancel="cancel"
|
||||||
placeholder="组件内原生 picker"
|
not-use="{{['years', 'seconds']}}"
|
||||||
placeholder-class="my-customer-class" />
|
/>
|
||||||
</zan-panel>
|
</zan-panel>
|
||||||
|
|
||||||
</doc-page>
|
</doc-page>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## DatetimePicker 时间选择
|
## DatetimePicker 时间选择
|
||||||
|
|
||||||
使用 picker 组件开发的时间日期组件,弥补小程序 picker 自身对于快速时间选择的不支持
|
使用 picker 组件开发的时间日期组件,弥补小程序 picker 自身对于快速时间选择的不支持。
|
||||||
|
|
||||||
### 示例代码
|
### 示例代码
|
||||||
|
|
||||||
@ -26,11 +26,10 @@
|
|||||||
|
|
||||||
| 名称 | 类型 | 是否必须 | 默认 | 描述 |
|
| 名称 | 类型 | 是否必须 | 默认 | 描述 |
|
||||||
| ----------------- | --------- | -------- | ------------------- | ----------------------------------------------------------------------------------------------------- |
|
| ----------------- | --------- | -------- | ------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||||
| value | null | `否` | 当前时间 | 初始化时间,传入的值会被 Date 构造函数转换为一个 Date 对象,不合法的值将抛出一个错误 |
|
| date | `String` | `否` | 当前时间 | 初始化时间,传入的值会被 Date 构造函数转换为一个 Date 对象,不合法的值将抛出一个错误 |
|
||||||
| placeholder-class | `String` | `否` | 无 | 自定义类,可改变 placeholder 样式,其他类无效,`picker-view` 为 true 时不支持 |
|
| placeholder-class | `String` | `否` | 无 | 自定义类,可改变 placeholder 样式,其他类无效,`picker-view` 为 true 时不支持 |
|
||||||
| placeholder | `String` | `否` | 请选择时间 | 设置 picker 的 placeholder |
|
| placeholder | `String` | `否` | 请选择时间 | 设置 picker 的 placeholder,`picker-view` 为 true 时不支持 |
|
||||||
| not-use | `Array` | `否` | 无 | 不需要显示的列 可选择`years`, `months`, `days`, `hours`, `minutes`, `seconds`中的多个 |
|
| not-use | `Array` | `否` | 无 | 不需要显示的列 可选择`years`, `months`, `days`, `hours`, `minutes`, `seconds`中的多个 |
|
||||||
| native | `Boolean` | `否` | 无 | 使用原生 picker,还是自定义的 picker(自定义 picker 滚动不如原生) |
|
|
||||||
| picker-view | `Boolean` | `否` | 无 | 如果为 true,相当于 picker-view 组件 |
|
| picker-view | `Boolean` | `否` | 无 | 如果为 true,相当于 picker-view 组件 |
|
||||||
| format | `String` | `否` | YYYY-MM-DD HH:mm:ss | 设置选中的时间显示的格式,支持 _YYYY,yyyy,YY,yy,MM,M,DD,dd,D,d,HH, hh,H,h,mm,m,ss,s_ |
|
| format | `String` | `否` | YYYY-MM-DD HH:mm:ss | 设置选中的时间显示的格式,支持 _YYYY,yyyy,YY,yy,MM,M,DD,dd,D,d,HH, hh,H,h,mm,m,ss,s_ |
|
||||||
| bindchange | `String` | `是` | 无 | 用户点击`确认`触发该事件,返回值为按“年,月,日,时,分,秒”顺序的数组,可以通过`detail.value`获取 |
|
| bindchange | `String` | `是` | 无 | 用户点击`确认`触发该事件,返回值为按“年,月,日,时,分,秒”顺序的数组,可以通过`detail.value`获取 |
|
||||||
@ -38,11 +37,10 @@
|
|||||||
|
|
||||||
### 方法
|
### 方法
|
||||||
|
|
||||||
| 名称 | 参数 | 描述 |
|
| 名称 | 参数 | 描述 |
|
||||||
| ------------ | ---- | ---- |
|
| ------------ | ---- | --------------------------------------------------------------- |
|
||||||
| getFormatStr | 无 | 返回 `format` 格式的字符串,在 `picker-view` 为 true 时比较实用 |
|
| getFormatStr | 无 | 返回 `format` 格式的字符串,在 `picker-view` 为 true 时比较实用 |
|
||||||
|
|
||||||
### 增强优化
|
### 增强优化
|
||||||
|
|
||||||
* 支持可选择时间区域限制
|
* 支持可选择时间区域限制
|
||||||
* 滚动优化
|
|
||||||
|
35
packages/datetime-picker/date-picker-view.wxml
Normal file
35
packages/datetime-picker/date-picker-view.wxml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<import src="./picker-view-column.wxml" />
|
||||||
|
|
||||||
|
<template name="date-picker-view">
|
||||||
|
<picker-view
|
||||||
|
value="{{ selected }}"
|
||||||
|
bindchange="change"
|
||||||
|
indicator-style="height: 50px;"
|
||||||
|
class="picker-visible">
|
||||||
|
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[0], className: 'year-view-column', hidden: !use['years'], tip: '年' }}"
|
||||||
|
/>
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[1], hidden: !use['months'], tip: '月' }}"
|
||||||
|
/>
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[2], hidden: !use['days'], tip: '日' }}"
|
||||||
|
/>
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[3], hidden: !use['hours'], tip: '时' }}"
|
||||||
|
/>
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[4], hidden: !use['minutes'], tip: '分' }}"
|
||||||
|
/>
|
||||||
|
<template
|
||||||
|
is="picker-view-column"
|
||||||
|
data="{{ data: dataList[5], hidden: !use['seconds'], tip: '秒' }}"
|
||||||
|
/>
|
||||||
|
</picker-view>
|
||||||
|
</template>
|
98
packages/datetime-picker/date-picker.js
Normal file
98
packages/datetime-picker/date-picker.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
const LIMIT_YEAR_COUNT = 50;
|
||||||
|
const { genNumber, iso2utc } = require('./utils')
|
||||||
|
|
||||||
|
module.exports = class DatePicker {
|
||||||
|
constructor(date = new Date()) {
|
||||||
|
this.types = ['year', 'month', 'day', 'hour', 'minute', 'second'];
|
||||||
|
this.months = genNumber(1, 12, 2);
|
||||||
|
this.hours = genNumber(0, 23, 2);
|
||||||
|
this.seconds = genNumber(0, 59, 2);
|
||||||
|
this.minutes = genNumber(0, 59, 2);
|
||||||
|
this._date = date
|
||||||
|
}
|
||||||
|
|
||||||
|
getYears(year) {
|
||||||
|
let mid = Math.floor(LIMIT_YEAR_COUNT / 2);
|
||||||
|
let min = year - mid;
|
||||||
|
let max = year + (LIMIT_YEAR_COUNT - mid);
|
||||||
|
return genNumber(min, max, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastDay(year, month) {
|
||||||
|
return month !== 12 ? new Date(
|
||||||
|
new Date(`${year}/${month + 1}/1`).getTime() - (24 * 60 * 60 * 1000)
|
||||||
|
).getDate() : 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
getData (date) {
|
||||||
|
date = date || this._date || new Date
|
||||||
|
|
||||||
|
// toUTCString ISO 格式部分 ios 手机会失败
|
||||||
|
if (typeof date === 'string' && date.indexOf('-') > 0) {
|
||||||
|
date = iso2utc(date)
|
||||||
|
}
|
||||||
|
|
||||||
|
let d = new Date(date);
|
||||||
|
console.log(d);
|
||||||
|
|
||||||
|
let y = d.getFullYear();
|
||||||
|
let m = d.getMonth() + 1;
|
||||||
|
let years = this.getYears(y);
|
||||||
|
let lastDay = this.lastDay(y, m);
|
||||||
|
let days = genNumber(1, lastDay, 2);
|
||||||
|
|
||||||
|
this._years = years;
|
||||||
|
this._dataList = [years, this.months, days, this.hours, this.minutes, this.seconds];
|
||||||
|
this._indexs = [25, m - 1, d.getDate() - 1, d.getHours(), d.getMinutes(), d.getSeconds()];
|
||||||
|
|
||||||
|
return {
|
||||||
|
dataList: this._dataList,
|
||||||
|
selected: this._indexs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(col, index) {
|
||||||
|
let type = this.types[col];
|
||||||
|
switch (type) {
|
||||||
|
case 'year':
|
||||||
|
return this._updateYear(col, index);
|
||||||
|
case 'month':
|
||||||
|
return this._updateMonth(col, index);
|
||||||
|
default:
|
||||||
|
this._indexs[col] = index;
|
||||||
|
return [{ col, index }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateYear(col, index, cb) {
|
||||||
|
let years = this._dataList[col];
|
||||||
|
let year = years[index];
|
||||||
|
|
||||||
|
this._dataList[col] = this.getYears(+year);
|
||||||
|
|
||||||
|
this._indexs[col] = Math.floor(LIMIT_YEAR_COUNT / 2);
|
||||||
|
|
||||||
|
return [{ col: 0, index: this._indexs[col], data: this._dataList[col] }]
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateMonth(col, index) {
|
||||||
|
let month = this._dataList[col][index];
|
||||||
|
let year = this._dataList[0][this._indexs[0]];
|
||||||
|
let lastDay = this.lastDay(+year, +month);
|
||||||
|
this._indexs[col] = index;
|
||||||
|
this._dataList[2] = genNumber(1, lastDay, 2);
|
||||||
|
this._indexs[2] = this._indexs[2] >= this._dataList[2].length ? this._dataList[2].length - 1 : this._indexs[2];
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
col: 1,
|
||||||
|
index
|
||||||
|
},
|
||||||
|
{
|
||||||
|
col: 2,
|
||||||
|
index: this._indexs[2],
|
||||||
|
data: this._dataList[2]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -1,145 +1,7 @@
|
|||||||
function partStartWithZero(num, strlen) {
|
const DatePicker = require('./date-picker')
|
||||||
let zeros = '';
|
const { genNumber, moment } = require('./utils')
|
||||||
while (zeros.length < strlen) {
|
|
||||||
zeros += '0';
|
|
||||||
}
|
|
||||||
return (zeros + num).slice(-strlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
function genNumber(begin, end, strlen) {
|
|
||||||
let nums = [];
|
|
||||||
while (begin <= end) {
|
|
||||||
nums.push(partStartWithZero(begin, strlen));
|
|
||||||
begin++;
|
|
||||||
}
|
|
||||||
return nums;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moment(date, formatStr = 'YYYY:MM:DD') {
|
|
||||||
if (!date && date !== 0) date = new Date();
|
|
||||||
|
|
||||||
date = new Date(date);
|
|
||||||
if (date.toString() === 'Invalid Date') throw new Error('Invalid Date');
|
|
||||||
|
|
||||||
let getDateValue = (method, fn) => (fn ? fn(date[`get${method}`]()) : date[`get${method}`]());
|
|
||||||
let map = new Map();
|
|
||||||
|
|
||||||
map.set(/(Y+)/i, () => getDateValue('FullYear', year => (year + '').substr(4 - RegExp.$1.length)));
|
|
||||||
map.set(/(M+)/, () => getDateValue('Month', month => partStartWithZero(month + 1, RegExp.$1.length)));
|
|
||||||
map.set(/(D+)/i, () => getDateValue('Date', date => partStartWithZero(date, RegExp.$1.length)));
|
|
||||||
map.set(/(H+)/i, () => getDateValue('Hours', hour => partStartWithZero(hour, RegExp.$1.length)));
|
|
||||||
map.set(/(m+)/, () => getDateValue('Minutes', minute => partStartWithZero(minute, RegExp.$1.length)));
|
|
||||||
map.set(/(s+)/, () => getDateValue('Seconds', second => partStartWithZero(second, RegExp.$1.length)));
|
|
||||||
|
|
||||||
for (const [reg, fn] of map) {
|
|
||||||
if (reg.test(formatStr)) {
|
|
||||||
formatStr = formatStr.replace(RegExp.$1, fn.call(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return formatStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LIMIT_YEAR_COUNT = 50;
|
|
||||||
class DatePicker {
|
|
||||||
constructor(format, date = new Date(), cb) {
|
|
||||||
this.types = ['year', 'month', 'day', 'hour', 'minute', 'second'];
|
|
||||||
this.months = genNumber(1, 12, 2);
|
|
||||||
this.hours = genNumber(0, 23, 2);
|
|
||||||
this.seconds = genNumber(0, 59, 2);
|
|
||||||
this.minutes = genNumber(0, 59, 2);
|
|
||||||
// this.format(format);
|
|
||||||
this.init(date, cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
getYears(year) {
|
|
||||||
let mid = Math.floor(LIMIT_YEAR_COUNT / 2);
|
|
||||||
let min = year - mid;
|
|
||||||
let max = year + (LIMIT_YEAR_COUNT - mid);
|
|
||||||
return genNumber(min, max, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastDay(year, month) {
|
|
||||||
return month !== 12 ? new Date(
|
|
||||||
new Date(`${year}/${month + 1}/1`).getTime() - (24 * 60 * 60 * 1000)
|
|
||||||
).getDate() : 31;
|
|
||||||
}
|
|
||||||
|
|
||||||
init(date, cb) {
|
|
||||||
let d = new Date(date);
|
|
||||||
let y = d.getFullYear();
|
|
||||||
let m = d.getMonth() + 1;
|
|
||||||
let years = this.getYears(y);
|
|
||||||
let lastDay = this.lastDay(y, m);
|
|
||||||
|
|
||||||
let days = genNumber(1, lastDay, 2);
|
|
||||||
|
|
||||||
this._years = years;
|
|
||||||
this._dataList = [years, this.months, days, this.hours, this.minutes, this.seconds];
|
|
||||||
this._indexs = [25, m - 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
|
|
||||||
cb && cb({
|
|
||||||
dataList: this._dataList,
|
|
||||||
indexs: this._indexs
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update(col, index, cb) {
|
|
||||||
let type = this.types[col];
|
|
||||||
switch (type) {
|
|
||||||
case 'year':
|
|
||||||
this._updateYear(col, index, cb);
|
|
||||||
break;
|
|
||||||
case 'month':
|
|
||||||
this._updateMonth(col, index, cb);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this._indexs[col] = index;
|
|
||||||
cb && cb({
|
|
||||||
dataList: this._dataList,
|
|
||||||
indexs: this._indexs,
|
|
||||||
updateColumn: col,
|
|
||||||
updateIndex: index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateYear(col, index, cb) {
|
|
||||||
let years = this._dataList[col];
|
|
||||||
let year = years[index];
|
|
||||||
|
|
||||||
this._dataList[col] = this.getYears(+year);
|
|
||||||
|
|
||||||
this._indexs[col] = Math.floor(LIMIT_YEAR_COUNT / 2);
|
|
||||||
cb && cb({
|
|
||||||
dataList: this._dataList,
|
|
||||||
indexs: this._indexs,
|
|
||||||
updateColumn: col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateMonth(col, index, cb) {
|
|
||||||
let month = this._dataList[col][index];
|
|
||||||
let year = this._dataList[0][this._indexs[0]];
|
|
||||||
let lastDay = this.lastDay(+year, +month);
|
|
||||||
this._indexs[col] = index;
|
|
||||||
this._dataList[2] = genNumber(1, lastDay, 2);
|
|
||||||
this._indexs[2] = this._indexs[2] >= this._dataList[2].length ? this._dataList[2].length - 1 : this._indexs[2];
|
|
||||||
cb && cb({
|
|
||||||
dataList: this._dataList,
|
|
||||||
indexs: this._indexs,
|
|
||||||
updateColumn: 2,
|
|
||||||
updateIndex: this._indexs[2]
|
|
||||||
});
|
|
||||||
cb && cb({
|
|
||||||
dataList: this._dataList,
|
|
||||||
indexs: this._indexs,
|
|
||||||
updateColumn: 1,
|
|
||||||
updateIndex: index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 组件内使用 this.indexs 好像有问题
|
|
||||||
let _indexs = [];
|
|
||||||
Component({
|
Component({
|
||||||
properties: {
|
properties: {
|
||||||
placeholder: {
|
placeholder: {
|
||||||
@ -150,15 +12,20 @@ Component({
|
|||||||
type: String,
|
type: String,
|
||||||
value: 'YYYY-MM-DD HH:mm:ss'
|
value: 'YYYY-MM-DD HH:mm:ss'
|
||||||
},
|
},
|
||||||
native: {
|
|
||||||
type: Boolean
|
|
||||||
},
|
|
||||||
pickerView: {
|
pickerView: {
|
||||||
type: Boolean
|
type: Boolean
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
type: String,
|
type: String,
|
||||||
value: new Date()
|
observer(value) {
|
||||||
|
if (value === ({}).toString()) {
|
||||||
|
throw new Error('参数必须是一个字符串')
|
||||||
|
}
|
||||||
|
if (/^[0-9]+$/.test(value)) {
|
||||||
|
value = +value
|
||||||
|
}
|
||||||
|
this.updateDate(value)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
notUse: {
|
notUse: {
|
||||||
type: Array
|
type: Array
|
||||||
@ -169,142 +36,133 @@ Component({
|
|||||||
transPos: [0, 0, 0, 0, 0, 0]
|
transPos: [0, 0, 0, 0, 0, 0]
|
||||||
},
|
},
|
||||||
attached() {
|
attached() {
|
||||||
this.use = {}
|
this.use = {};
|
||||||
;['years', 'months', 'days', 'hours', 'minutes', 'seconds'].forEach((item) => {
|
|
||||||
if ((this.data.notUse || []).indexOf(item) === -1) { this.use[item] = true }
|
['years', 'months', 'days', 'hours', 'minutes', 'seconds'].forEach((item) => {
|
||||||
|
if ((this.data.notUse || []).indexOf(item) === -1) {
|
||||||
|
this.use[item] = true
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.setData({ use: this.use });
|
|
||||||
this.data.pickerView && !this.data.native && this.showPicker();
|
this.picker = new DatePicker(this.data.date)
|
||||||
},
|
|
||||||
ready() {
|
let { dataList, selected } = this.picker.getData(this.data.date)
|
||||||
// 微信 bug,如果不先定义会导致不能选中
|
|
||||||
|
// 鬼他么知道为什么 dataList, selected 不能一起 setData
|
||||||
this.setData({
|
this.setData({
|
||||||
"dataList":[
|
use: this.use,
|
||||||
[
|
dataList
|
||||||
"2018","2019","2020","2021","2022","2023","2024","2025","2026","2027","2028","2029","2030","2031","2032","2033","2034","2035","2036","2037","2038","2039","2040","2041","2042","2043"
|
}, () => {
|
||||||
],
|
this.setData({
|
||||||
genNumber(1, 12, 2),
|
selected
|
||||||
genNumber(0, 31, 2),
|
})
|
||||||
genNumber(0, 23, 2),
|
});
|
||||||
genNumber(0, 59, 2),
|
|
||||||
genNumber(0, 59, 2)
|
this._indexs = selected
|
||||||
]
|
|
||||||
})
|
|
||||||
this.picker = new DatePicker(this.data.format, this.data.date, this.updatePicker.bind(this));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
updatePicker({ dataList, indexs, updateColumn, updateIndex }) {
|
updatePicker(updateData = []) {
|
||||||
let updateData = {};
|
let _updateData = {};
|
||||||
_indexs = indexs;
|
|
||||||
// 指定更新某列数据,表示某列数据更新
|
for (const { col, index, data } of updateData) {
|
||||||
if (updateColumn) {
|
if (~index && this._indexs[col] !== index || col === 0) {
|
||||||
updateData[`transPos[${updateColumn}]`] = -36 * _indexs[updateColumn];
|
_updateData[`selected[${col}]`] = index // 更新索引
|
||||||
updateData[`dataList[${updateColumn}]`] = dataList[updateColumn];
|
this._indexs[col] = index
|
||||||
}
|
}
|
||||||
// 指定更新某列索引,表示某列数据选中的索引已更新
|
|
||||||
if (typeof updateIndex !== 'undefined') {
|
if (data) {
|
||||||
updateData[`transPos[${updateColumn}]`] = -36 * _indexs[updateColumn];
|
_updateData[`dataList[${col}]`] = data;
|
||||||
updateData[`selected[${updateColumn}]`] = indexs[updateColumn];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只在初始化时设置全部的值,其他的都局部更新
|
this.setData(_updateData);
|
||||||
if (!updateColumn && typeof updateIndex === 'undefined') {
|
},
|
||||||
updateData = { dataList, selected: indexs };
|
|
||||||
_indexs.forEach((item, index) => {
|
|
||||||
updateData[`transPos[${index}]`] = -item * 36;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setData(updateData);
|
updateDate (date) {
|
||||||
|
let { dataList, selected } = this.picker.getData(date)
|
||||||
|
this._indexs = selected
|
||||||
|
|
||||||
|
// 好像必须要等到 datalist 完成
|
||||||
|
this.setData({ dataList }, () => {
|
||||||
|
this.setData({
|
||||||
|
selected,
|
||||||
|
text: this.getFormatStr()
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
touchmove(e) {
|
|
||||||
let { changedTouches, target } = e;
|
|
||||||
let col = target.dataset.col;
|
|
||||||
let { clientY } = changedTouches[0];
|
|
||||||
if (!col) return;
|
|
||||||
|
|
||||||
let updateData = {};
|
|
||||||
let itemLength = this.data.dataList[col].length;
|
|
||||||
updateData[`transPos[${col}]`] = this.startTransPos + (clientY - this.startY);
|
|
||||||
if (updateData[`transPos[${col}]`] >= 0) {
|
|
||||||
updateData[`transPos[${col}]`] = 0;
|
|
||||||
} else if (-(itemLength - 1) * 36 >= updateData[`transPos[${col}]`]) {
|
|
||||||
updateData[`transPos[${col}]`] = -(itemLength - 1) * 36;
|
|
||||||
}
|
|
||||||
this.setData(updateData);
|
|
||||||
},
|
|
||||||
touchStart(e) {
|
|
||||||
let { target, changedTouches } = e;
|
|
||||||
let col = target.dataset.col;
|
|
||||||
let touchData = changedTouches[0];
|
|
||||||
if (!col) return;
|
|
||||||
|
|
||||||
this.startY = touchData.clientY;
|
|
||||||
this.startTime = e.timeStamp;
|
|
||||||
this.startTransPos = this.data.transPos[col];
|
|
||||||
},
|
|
||||||
touchEnd(e) {
|
|
||||||
let { col } = e.target.dataset;
|
|
||||||
if (!col) return;
|
|
||||||
let pos = this.data.transPos[col];
|
|
||||||
let itemIndex = Math.round(pos / 36);
|
|
||||||
|
|
||||||
this.columnchange({ detail: { column: +col, value: -itemIndex } });
|
|
||||||
},
|
|
||||||
columnchange(e) {
|
|
||||||
let { column, value } = e.detail;
|
|
||||||
_indexs[column] = value;
|
|
||||||
this.picker.update(column, value, this.updatePicker.bind(this));
|
|
||||||
this.data.pickerView && !this.data.native && this.change({detail: {value: _indexs}})
|
|
||||||
},
|
|
||||||
getFormatStr() {
|
getFormatStr() {
|
||||||
let date = new Date()
|
let date = new Date();
|
||||||
;['FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds'].forEach((key, index) => {
|
['FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds'].forEach((key, index) => {
|
||||||
let value = this.data.dataList[index][_indexs[index]];
|
let value = this.data.dataList[index][this._indexs[index]];
|
||||||
if (key === 'Month') {
|
if (key === 'Month') {
|
||||||
value = +this.data.dataList[index][_indexs[index]] - 1;
|
value = +this.data.dataList[index][this._indexs[index]] - 1;
|
||||||
}
|
}
|
||||||
date[`set${key}`](+value);
|
date[`set${key}`](+value);
|
||||||
});
|
});
|
||||||
|
|
||||||
return moment(date, this.data.format);
|
return moment(date, this.data.format);
|
||||||
},
|
},
|
||||||
|
|
||||||
showPicker() {
|
showPicker() {
|
||||||
this.setData({ show: true });
|
this.setData({
|
||||||
|
show: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
hidePicker(e) {
|
hidePicker(e) {
|
||||||
let { action } = e.currentTarget.dataset;
|
let { action } = e.currentTarget.dataset;
|
||||||
this.setData({ show: false });
|
|
||||||
|
this.setData({
|
||||||
|
show: false
|
||||||
|
});
|
||||||
|
|
||||||
if (action === 'cancel') {
|
if (action === 'cancel') {
|
||||||
this.cancel({ detail: {} });
|
this.cancel({
|
||||||
|
detail: {}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.change({ detail: { value: _indexs } });
|
this.change({
|
||||||
|
detail: {
|
||||||
|
value: this._indexs
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
columnchange(e) {
|
||||||
|
let { column, value } = e.detail;
|
||||||
|
let updateData = this.picker.update(column, value);
|
||||||
|
this.updatePicker(updateData)
|
||||||
|
},
|
||||||
|
|
||||||
change(e) {
|
change(e) {
|
||||||
let { value } = e.detail;
|
let { value } = e.detail;
|
||||||
|
|
||||||
let data = this.data.dataList.map((item, index) => {
|
let data = this.data.dataList.map((item, index) => {
|
||||||
return +item[value[index]];
|
return +item[value[index]];
|
||||||
});
|
});
|
||||||
|
|
||||||
this.triggerEvent('change', { value: data });
|
this.triggerEvent('change', {
|
||||||
|
value: data
|
||||||
|
});
|
||||||
|
|
||||||
// 为了支持原生 picker view,每次 change 都需要手动 columnchange
|
// 手动触发 columnchange
|
||||||
if (this.data.pickerView && this.data.native) {
|
for (let index = 0; index < value.length; index++) {
|
||||||
for (let index = 0; index < value.length; index++) {
|
if (this._indexs[index] !== value[index]) {
|
||||||
if (_indexs[index] !== value[index]) {
|
this.columnchange({
|
||||||
this.columnchange({
|
detail: {
|
||||||
detail: {
|
column: index,
|
||||||
column: index, value: value[index]
|
value: value[index]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break // 这里每次只处理一列,否则会出现日期值为 undefined 的情况
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setData({ text: this.getFormatStr() });
|
this.setData({
|
||||||
|
text: this.getFormatStr()
|
||||||
|
});
|
||||||
},
|
},
|
||||||
cancel(e) {
|
cancel(e) {
|
||||||
this.triggerEvent('cancel', e.detail);
|
this.triggerEvent('cancel', e.detail);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"component": true
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"pop-manager": "../common/pop-manager/index"
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,111 +1,18 @@
|
|||||||
<block wx:if="{{ pickerView }}">
|
<import src="./date-picker-view.wxml" />
|
||||||
<picker-view
|
|
||||||
wx:if="{{ native }}"
|
|
||||||
value="{{ selected }}"
|
|
||||||
bindchange="change"
|
|
||||||
indicator-style="height: 50px;"
|
|
||||||
class="picker-visible">
|
|
||||||
<picker-view-column>
|
|
||||||
<view wx:for="{{dataList[0]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
|
||||||
</picker-view-column>
|
|
||||||
|
|
||||||
<picker-view-column>
|
<view wx:if="{{ !pickerView }}" bindtap="showPicker" class="placeholder-class">{{text || placeholder}}</view>
|
||||||
<view wx:for="{{dataList[1]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
|
||||||
</picker-view-column>
|
|
||||||
|
|
||||||
<picker-view-column>
|
<view wx:if="{{ pickerView }}" class="picker-view">
|
||||||
<view wx:for="{{dataList[2]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
<template is="date-picker-view" data="{{ dataList, selected, use }}" />
|
||||||
</picker-view-column>
|
</view>
|
||||||
|
<view wx:else>
|
||||||
<picker-view-column>
|
<pop-manager show="{{ show }}" type="bottom" >
|
||||||
<view wx:for="{{dataList[3]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
<view class="picker">
|
||||||
</picker-view-column>
|
<view class="picker-action">
|
||||||
|
<view data-action="cancel" bindtap="hidePicker">取消</view>
|
||||||
<picker-view-column>
|
<view data-action="change" bindtap="hidePicker">确认</view>
|
||||||
<view wx:for="{{dataList[4]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
</view>
|
||||||
</picker-view-column>
|
<template is="date-picker-view" data="{{ dataList, selected, use }}" />
|
||||||
|
|
||||||
<picker-view-column>
|
|
||||||
<view wx:for="{{dataList[5]}}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
|
||||||
</picker-view-column>
|
|
||||||
</picker-view>
|
|
||||||
</block>
|
|
||||||
<block wx:else>
|
|
||||||
<picker
|
|
||||||
wx:if="{{native}}"
|
|
||||||
mode="multiSelector"
|
|
||||||
range="{{ dataList }}"
|
|
||||||
value="{{ selected }}"
|
|
||||||
bindchange="change"
|
|
||||||
bindcolumnchange="columnchange"
|
|
||||||
bindcancel="cancel" >
|
|
||||||
<view class="placeholder-class">
|
|
||||||
{{text || placeholder}}
|
|
||||||
</view>
|
</view>
|
||||||
</picker>
|
</pop-manager>
|
||||||
</block>
|
|
||||||
<view data-action="cancel" bindtap="hidePicker" class="picker-mask {{show && !pickerView ? 'show' : ''}}"></view>
|
|
||||||
<view wx:if="{{ !native }}" class="data-time-picker {{ pickerView && 'picker-view' }}">
|
|
||||||
<view bindtap="showPicker" wx:if="{{ !pickerView }}" class="placeholder-class">{{text || placeholder}}</view>
|
|
||||||
<view class="picker {{show ? 'picker-visible' : ''}}">
|
|
||||||
<view wx:if="{{!pickerView}}" class="picker-action">
|
|
||||||
<view data-action="cancel" bindtap="hidePicker">取消</view>
|
|
||||||
<view data-action="change" bindtap="hidePicker">确认</view>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
catchtouchstart="touchStart"
|
|
||||||
catchtouchend="touchEnd"
|
|
||||||
catchtouchmove="touchmove" class="picker-cols">
|
|
||||||
|
|
||||||
<view wx:if="{{use['years']}}" data-col="0" class="col">
|
|
||||||
<view data-col="0" style="transform: translateY({{ transPos[0] }}px)">
|
|
||||||
<view data-col="0" class="{{ index === selected[0] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index"
|
|
||||||
wx:for="{{dataList[0]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['years']}}" data-col="0" class="fixed-col">年</view>
|
|
||||||
|
|
||||||
<view wx:if="{{use['months']}}" data-col="1" class="col">
|
|
||||||
<view data-col="1" style="transform: translateY({{ transPos[1] }}px)">
|
|
||||||
<view data-col="1" class="{{ index === selected[1] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index"
|
|
||||||
wx:for="{{dataList[1]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['months']}}" data-col="1" class="fixed-col">月</view>
|
|
||||||
|
|
||||||
<view wx:if="{{use['days']}}" data-col="2" class="col">
|
|
||||||
<view data-col="2" style="transform: translateY({{ transPos[2] }}px)">
|
|
||||||
<view data-col="2" class="{{ index === selected[2] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index" wx:for="{{dataList[2]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['days']}}" data-col="2" class="fixed-col">日</view>
|
|
||||||
|
|
||||||
<view wx:if="{{use['hours']}}" data-col="3" class="col">
|
|
||||||
<view data-col="3" style="transform: translateY({{ transPos[3] }}px)">
|
|
||||||
<view data-col="3" class="{{ index === selected[3] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index" wx:for="{{dataList[3]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['hours']}}" data-col="3" class="fixed-col">时</view>
|
|
||||||
|
|
||||||
<view wx:if="{{use['minutes']}}" data-col="4" class="col">
|
|
||||||
<view data-col="4" style="transform: translateY({{ transPos[4] }}px)">
|
|
||||||
<view data-col="4" class="{{ index === selected[4] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index" wx:for="{{dataList[4]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['minutes']}}" data-col="4" class="fixed-col">分</view>
|
|
||||||
|
|
||||||
<view wx:if="{{use['seconds']}}" data-col="5" class="col">
|
|
||||||
<view data-col="5" style="transform: translateY({{ transPos[5] }}px)">
|
|
||||||
<view data-col="5" class="{{ index === selected[5] ? 'select-item' : '' }} cell"
|
|
||||||
wx:for-index="index" wx:for="{{dataList[5]}}" wx:key="*this">{{item}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view wx:if="{{use['seconds']}}" data-col="5" class="fixed-col">秒</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
@ -1,110 +1,53 @@
|
|||||||
.picker-view-column {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.placeholder-class {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.picker {
|
|
||||||
position: fixed;
|
|
||||||
bottom: -100px;
|
|
||||||
width: 100vw;
|
|
||||||
left: 0;
|
|
||||||
background: #fff;
|
|
||||||
z-index: 999;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 0;
|
|
||||||
transition: height ease-in 0.3s;
|
|
||||||
}
|
|
||||||
.picker-view .picker {
|
|
||||||
position: relative;
|
|
||||||
bottom: auto;
|
|
||||||
left: auto;
|
|
||||||
width: 100%;
|
|
||||||
z-index: auto;
|
|
||||||
}
|
|
||||||
.picker-visible {
|
.picker-visible {
|
||||||
height: 236px;
|
height: 236px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
.picker-view .picker-visible {
|
|
||||||
height: 200px;
|
picker-view-column.year-view-column {
|
||||||
|
width: 50px;
|
||||||
|
flex: 2;
|
||||||
}
|
}
|
||||||
.picker-mask {
|
picker-view-column {
|
||||||
position: fixed;
|
width: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.view-column-tip {
|
||||||
|
height: 235px;
|
||||||
|
line-height: 235px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
z-index: 12;
|
||||||
bottom: 100vh;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
.picker-mask.show {
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 998;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.picker .picker-action {
|
.picker .picker-action {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border-bottom: 1rpx solid #e5e5e5;
|
bottom: 235px;
|
||||||
|
padding: 0 15px;
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
background: #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 15px;
|
|
||||||
}
|
}
|
||||||
.picker-action view:last-child {
|
.picker-action view:last-child {
|
||||||
color: #1aad16;
|
color: #1aad16;
|
||||||
}
|
}
|
||||||
.picker .picker-cols {
|
|
||||||
display: flex;
|
.picker picker-view {
|
||||||
flex: 1;
|
|
||||||
margin: 10px 5px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 180px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.picker-cols .fixed-col {
|
|
||||||
color: #999;
|
|
||||||
margin-left: 5px;
|
|
||||||
height:100%;
|
|
||||||
line-height:180px;
|
|
||||||
}
|
|
||||||
.picker-cols .col {
|
|
||||||
transform-origin: center;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.picker-cols .col .select-item {
|
|
||||||
color: #333;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.picker-cols .col {
|
|
||||||
flex: 1;
|
|
||||||
text-align: right;
|
|
||||||
color: #aaa;
|
|
||||||
height: 180px;
|
|
||||||
position: relative;
|
|
||||||
padding-top: 79px;
|
|
||||||
}
|
|
||||||
.picker-cols .col > view {
|
|
||||||
transition: transform 0.0003s;
|
|
||||||
}
|
|
||||||
.picker-cols .col .cell {
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
.picker-cols::after, .picker-cols::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 72px;
|
|
||||||
width: calc(100% - 10px);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.picker-cols::before {
|
|
||||||
top: 0;
|
|
||||||
border-bottom: 1rpx solid #e5e5e5;
|
|
||||||
}
|
|
||||||
.picker-cols::after {
|
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
border-top: 1rpx solid #e5e5e5;
|
background: #fff;
|
||||||
}
|
width: 100vw;
|
||||||
|
}
|
6
packages/datetime-picker/picker-view-column.wxml
Normal file
6
packages/datetime-picker/picker-view-column.wxml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<template name="picker-view-column">
|
||||||
|
<picker-view-column class="{{ className }} {{ hidden && 'hidden'}}">
|
||||||
|
<view wx:for="{{ data }}" style="line-height: 50px" wx:key="*this">{{item}}</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<view class="view-column-tip {{ hidden && 'hidden'}}">{{ tip }}</view>
|
||||||
|
</template>
|
79
packages/datetime-picker/utils.js
Normal file
79
packages/datetime-picker/utils.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
function partStartWithZero(num, strlen) {
|
||||||
|
let zeros = '';
|
||||||
|
while (zeros.length < strlen) {
|
||||||
|
zeros += '0';
|
||||||
|
}
|
||||||
|
return (zeros + num).slice(-strlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.genNumber = function genNumber(begin, end, strlen) {
|
||||||
|
let nums = [];
|
||||||
|
while (begin <= end) {
|
||||||
|
nums.push(partStartWithZero(begin, strlen));
|
||||||
|
begin++;
|
||||||
|
}
|
||||||
|
return nums;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.moment = function moment(date, formatStr = 'YYYY:MM:DD') {
|
||||||
|
if (!date && date !== 0) date = new Date();
|
||||||
|
|
||||||
|
date = new Date(date);
|
||||||
|
if (date.toString() === 'Invalid Date') throw new Error('Invalid Date');
|
||||||
|
|
||||||
|
let getDateValue = (method, fn) => (fn ? fn(date[`get${method}`]()) : date[`get${method}`]());
|
||||||
|
let map = new Map();
|
||||||
|
|
||||||
|
map.set(/(Y+)/i, () => getDateValue('FullYear', year => (year + '').substr(4 - RegExp.$1.length)));
|
||||||
|
map.set(/(M+)/, () => getDateValue('Month', month => partStartWithZero(month + 1, RegExp.$1.length)));
|
||||||
|
map.set(/(D+)/i, () => getDateValue('Date', date => partStartWithZero(date, RegExp.$1.length)));
|
||||||
|
map.set(/(H+)/i, () => getDateValue('Hours', hour => partStartWithZero(hour, RegExp.$1.length)));
|
||||||
|
map.set(/(m+)/, () => getDateValue('Minutes', minute => partStartWithZero(minute, RegExp.$1.length)));
|
||||||
|
map.set(/(s+)/, () => getDateValue('Seconds', second => partStartWithZero(second, RegExp.$1.length)));
|
||||||
|
|
||||||
|
for (const [reg, fn] of map) {
|
||||||
|
if (reg.test(formatStr)) {
|
||||||
|
formatStr = formatStr.replace(RegExp.$1, fn.call(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.iso2utc = function (string) {
|
||||||
|
let regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
|
||||||
|
if (string) {
|
||||||
|
let d = string.match(new RegExp(regexp));
|
||||||
|
let offset = 0;
|
||||||
|
let date = new Date(d[1], 0, 1);
|
||||||
|
|
||||||
|
if (d[3]) {
|
||||||
|
date.setMonth(d[3] - 1);
|
||||||
|
}
|
||||||
|
if (d[5]) {
|
||||||
|
date.setDate(+d[5]);
|
||||||
|
}
|
||||||
|
if (d[7]) {
|
||||||
|
date.setHours(d[7]);
|
||||||
|
}
|
||||||
|
if (d[8]) {
|
||||||
|
date.setMinutes(d[8]);
|
||||||
|
}
|
||||||
|
if (d[10]) {
|
||||||
|
date.setSeconds(d[10]);
|
||||||
|
}
|
||||||
|
if (d[12]) {
|
||||||
|
date.setMilliseconds(Number("0." + d[12]) * 1000);
|
||||||
|
}
|
||||||
|
if (d[14]) {
|
||||||
|
offset = (Number(d[16]) * 60) + Number(d[17]);
|
||||||
|
offset *= ((d[15] == '-') ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset -= date.getTimezoneOffset();
|
||||||
|
|
||||||
|
return (Number(date) + (offset * 60 * 1000));
|
||||||
|
} else {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user