使用picker-view来封装成的一个时间选择器
开始时间是当前时间的一个小时之后,秒默认是0秒
可能还有一些情况未处理,后续发现再更新
js文件
第一版:略繁琐
// components/pickerTime/pickerTime.js
Component({
/**
* 组件的属性列表
*/
properties: {},
/**
* 组件的初始数据
*/
data: {
years: [], //年-月列表
days: [], //日期列表
hours: [], //小时列表
minutes: [], //分支列表
pickerTime: [0, 0, 0, 0], //列表选定的列集合
timeRegion: "", //选定的时间字符串
hList1: [], //未满24小时(第一天的小时列表)
hList2: [], //完整24小时(第二天的小时列表)
mList1: [], //第一个小时的分钟列表(不一定满60分钟)
mList2: [], //满60分钟
mList3: [], //最后一小时的分钟列表(不一定满60分钟)
dList: [], //日期列表(最多有两个)
yList: [], //年/月列表(最多有两个)
yTime: 0, //已选年-月索引
dTime: 0, //已选日期索引
hTime: 0, //已选小时索引
mTime: 0, //已选分钟索引
isNext: false, //是否跨年/月
},
lifetimes: {
attached: function () {
// 在组件实例进入页面节点树时执行
this.handleTime();
},
},
/**
* 组件的方法列表
*/
methods: {
// 处理时间
handleTime() {
// 日期
const dList = this.handleD();
console.log(dList, 121212);
// 小时
const hList = this.handleH();
console.log(hList, 11111);
// 分钟
const mList = this.handleM();
console.log(mList, 3333);
this.handleTimeRegion();
},
// 获取当前月有多少天
getMonth(date) {
let dt = new Date(date);
const month = dt.getMonth();
dt.setMonth(month + 1);
dt.setDate(0);
return dt.getDate();
},
// 处理分钟列表
handleM() {
// 分钟列表
let mList1 = [],
mList2 = [],
mList3 = []; //分钟列表
const date = new Date();
// 获取分钟列表
let M = date.getMinutes(); //获取当前分钟数(0-59)
let H = date.getHours() + 1; //获取当前小时数(0-23)
// H = 23;
// M = 0;
// 到60分还剩多少分钟
let surplusM = 60 - M;
for (let i = 0; i < surplusM + 1; i++) {
let mm = M + i;
if (mm < 60) {
mm = mm < 10 ? "0" + mm : mm;
mList1.push(mm);
}
}
//完整60分钟
for (let i = 0; i < 60; i++) {
const mm = i < 10 ? "0" + i : i;
mList2.push(mm);
}
// 判断当前是00分时,最后一个小时是00-59分
if (M == 0) {
M = 60;
}
// 最后一小时的分钟
for (let i = 0; i < M; i++) {
const mm = i < 10 ? "0" + i : i;
mList3.push(mm);
}
this.setData({
mList1,
mList2,
mList3,
minutes: mList1,
});
return [mList1, mList2, mList3];
},
// 处理小时列表
handleH() {
// 小时列表
let hList1 = [],
hList2 = []; //小时列表
const date = new Date();
// 获取小时列表
let H = date.getHours() + 1; //获取当前小时数(0-23)
let M = date.getMinutes(); //获取当前分钟数(0-59)
// M = 0;
// H = 23;
// 到24点还剩多少小时
let surplusH = 24 - H;
// 当前是零点,小时+1
if (H == 0) {
H++;
}
for (let i = 0; i < surplusH; i++) {
let hh = H + i;
if (hh < 24) {
hh = hh < 10 ? "0" + hh : hh;
hList1.push(hh);
}
}
// 第二天剩余的小时
for (let i = 0; i < H; i++) {
const hh = i < 10 ? "0" + i : i;
hList2.push(hh);
}
// 判断当前是00分时,第二天要去掉最后一个的一个小时
if (M == 0) {
hList2.pop();
}
// 判断当前是23点的,hList2添加23点的数据,hList1与hList2一致
if (H == 23) {
hList2.push(23);
hList1 = hList2;
}
this.setData({
hList1,
hList2,
hours: H == 23 ? hList2 : hList1,
});
return [hList1, hList2];
},
// 处理日期列表
handleD() {
const date = new Date();
let YY = date.getFullYear(); //获取完整的年份(4位,1970-???)
let isNext = false; //是否跨月/年
let MM = date.getMonth() + 1; //获取当前月份(0-11,0代表1月),
let H = date.getHours(); //获取当前小时数(0-23)
let M = date.getMinutes(); //获取当前分钟数(0-59)
// H = 23;
MM = MM < 10 ? "0" + MM : MM;
// 返回当月有多少天
const allM = this.getMonth(YY + "-" + MM + "-" + "01");
// 获取日期列表
let DD = date.getDate(); //获取当前日(1-31)
const DDD = DD < 10 ? "0" + DD : DD;
let dList = [DDD];
let yList = [`${YY}-${MM}`];
// 判断是否是零点零分
let isZero = H == 0 && M == 0;
// 不是零点零分,就跨天,添加第二天
if (!isZero) {
// 当天是否是最后一天,最后一天+1,就到下一个月的1号
let dd = DD + 1 > allM ? 1 : DD + 1;
dd = dd < 10 ? "0" + dd : dd;
dList.push(dd);
}
// DD = 31;
// MM = 12;
// 判断第二天是下个月的第一天,月份+1,(不是12月)
if (DD + 1 > allM && MM != 12 && !isZero) {
MM = Number(MM) + 1;
yList.push(`${YY}-${MM < 10 ? "0" + MM : MM}`);
isNext = true;
} else if (MM == 12 && DD + 1 > allM && !isZero) {
// 是12月份,并且是31号,年份+1,月份改为1月份
YY = YY + 1;
MM = "01";
isNext = true;
yList.push(`${YY}-${MM}`);
}
// 判断是否是23点,日期列表dList删除第一个,isNext为false,不跨年/月
if (H == 23 && dList.length > 1) {
dList.shift();
isNext = false;
// 判断如果有跨年/月的,有的话删除yList第一个
if (yList.length > 1) {
yList.shift();
}
}
const days = isNext ? [dList[0]] : dList;
this.setData({
dList,
days,
years: yList,
yList,
isNext,
});
return dList;
},
// 切换处理
bindChange({ detail }) {
console.log(detail, 2222);
const data = detail.value;
// 索引
let yTime = this.data.yTime;
let dTime = this.data.dTime;
let hTime = this.data.hTime;
let mTime = data[3];
// 第一个小时
let isFirst = true;
// 最后一个小时
let isLast = false;
// 年/月切换
if (data[0] != this.data.yTime) {
yTime = data[0];
dTime = 0;
hTime = 0;
mTime = 0;
}
// 日期切换
if (data[1] != this.data.dTime) {
dTime = data[1];
hTime = 0;
mTime = 0;
}
// 小时切换
if (data[2] != this.data.hTime) {
hTime = data[2];
mTime = 0;
}
// 分钟切换
if (data[3] != this.data.mTime) {
mTime = data[3];
}
// 是否是第一个小时
isFirst = dTime == 0 && hTime == 0;
// 是否是最后一个小时
isLast =
dTime == this.data.days.length - 1 &&
hTime == this.data.hours.length - 1;
let noNextM = true;
//当选择第二个月份日期
if (data[0] == 1) {
noNextM = false;
// 设置不是第一个小时
isFirst = false;
// 判断小时是否切换
if (data[2] != this.data.hTime) {
// 判断是不是最后一个小时,不是最后一个小时,分钟列表是满60
isFirst = data[2] != this.data.hours.length - 1;
}
// 判断是否是最后一个钟
isLast = hTime == this.data.hours.length - 1;
}
// 判断是否只有一个月份
const isYears = this.data.years.length == 1;
// days:判断是否是只有一个月份,只有一个月份,值为整个dList;若有两个月份的,则再判断选择了第一个月份(值为dList的第一个元素)还是第二个月份(值为dList的第二个元素)
// hours:先判断是不是选的第二个月份以及是否是第一天
// minutes:第一天的第一个小时(值为mList1),第二天的最后一个小时(值为mList3),其他中间时间为mList2
this.setData({
days: isYears
? this.data.dList
: yTime == 0
? [this.data.dList[0]]
: [this.data.dList[1]],
hours: dTime == 0 && noNextM ? this.data.hList1 : this.data.hList2,
minutes: isFirst
? this.data.mList1
: isLast
? this.data.mList3
: this.data.mList2,
pickerTime: [yTime, dTime, hTime, mTime],
yTime,
dTime,
hTime,
mTime,
});
this.handleTimeRegion();
},
// 处理最后生成的pickerTime字符串
handleTimeRegion() {
const data = this.data.pickerTime;
const y = this.data.years[data[0]];
const d = this.data.days[data[1]];
const h = this.data.hours[data[2]];
const m = this.data.minutes[data[3]];
const timeRegion = y + "-" + d + " " + h + ":" + m + ":" + "00";
this.setData({
timeRegion,
});
},
// 取消
onCancel() {
const obj = {
timeRegion: "",
isPicker: false,
};
this.triggerEvent("onselect", obj);
},
// 确认
onChecking() {
const obj = {
timeRegion: this.data.timeRegion,
isPicker: true,
};
this.triggerEvent("onselect", obj);
},
},
});
第二版js文件:根据当前时间的时间戳A与24小时之后的时间戳B两者来进行处理获取对应的列表
// components/pickerTime/pickerTime.js
Component({
/**
* 组件的属性列表
*/
properties: {},
/**
* 组件的初始数据
*/
data: {
years: [], //年-月列表
days: [], //日期列表
hours: [], //小时列表
minutes: [], //分支列表
pickerTime: [0, 0, 0, 0], //列表选定的列集合
timeRegion: "", //选定的时间字符串
hList1: [], //未满24小时(第一天的小时列表)
hList2: [], //完整24小时(第二天的小时列表)
mList1: [], //第一个小时的分钟列表(不一定满60分钟)
mList2: [], //满60分钟
mList3: [], //最后一小时的分钟列表(不一定满60分钟)
dList: [], //日期列表(最多有两个)
yList: [], //年/月列表(最多有两个)
yTime: 0, //已选年-月索引
dTime: 0, //已选日期索引
hTime: 0, //已选小时索引
mTime: 0, //已选分钟索引
hList: [], //所有小时列表(24)
},
lifetimes: {
attached: function () {
// 在组件实例进入页面节点树时执行
this.handleTime();
},
},
/**
* 组件的方法列表
*/
methods: {
// 处理时间
handleTime() {
this.getPastTime();
this.handleTimeRegion();
},
// 切换处理
bindChange({ detail }) {
console.log(detail, 2222);
const data = detail.value;
// 索引
let yTime = this.data.yTime;
let dTime = this.data.dTime;
let hTime = this.data.hTime;
let mTime = 0;
let minutes = this.data.minutes;
let hours = this.data.hours;
// 年/月切换
// 只有跨月(跨年)才会有机会切换
if (data[0] != this.data.yTime) {
yTime = data[0];
// 如跨月(跨年)第一个日期是上个月的,第二个日期是下个月的
dTime = data[0];
hTime = 0;
mTime = 0;
// 如果是第一天,小时列表为hList1,否则为hList2
hours = dTime == 0 ? this.data.hList1 : this.data.hList2;
minutes = dTime == 0 ? this.data.mList1 : this.data.mList3;
}
// 日期切换
if (data[1] != this.data.dTime) {
dTime = data[1];
hTime = 0;
mTime = 0;
// 如果有跨月/年,年月和日要同步
if (this.data.yList.length > 1) {
yTime = data[1];
}
// 如果是第一天,小时列表为hList1,否则为hList2
hours = data[1] == 0 ? this.data.hList1 : this.data.hList2;
minutes = data[1] == 0 ? this.data.mList1 : this.data.mList3;
}
// 小时切换
if (data[2] != this.data.hTime) {
// 切换到第一天的第一个小时
if (data[0] == 0 && data[1] == 0 && data[2] == 0) {
minutes = this.data.mList1;
} else if (
data[0] == this.data.yList.length - 1 &&
data[1] == 1 &&
data[2] == this.data.hList2.length - 1
) {
// 第二天的最后一个小时
minutes = this.data.mList2;
} else {
// 中间小时
minutes = this.data.mList3;
}
hTime = data[2];
mTime = 0;
}
// 分钟切换
if (data[3] != this.data.mTime) {
mTime = data[3];
}
this.setData({
days: this.data.dList,
hours,
minutes,
pickerTime: [yTime, dTime, hTime, mTime],
yTime,
dTime,
hTime,
mTime,
});
this.handleTimeRegion();
},
getPastTime() {
// 获取24小时之后的时间戳
const nextTime = new Date().getTime() + 24 * 60 * 60 * 1000;
// 一个小时之后的时间戳
const currentTime = new Date().getTime() + 60 * 60 * 1000;
// 处理年月
this.getYM(currentTime, nextTime);
// 处理日
this.getDay(currentTime, nextTime);
// 处理小时
this.getHour(currentTime, nextTime);
// 处理分钟
this.getMinute(currentTime, nextTime);
},
// 获取年月列表
getYM(currentTime, nextTime) {
const yTime1 = this.timeFormat(currentTime, "getFullYear");
const yTime2 = this.timeFormat(nextTime, "getFullYear");
let mTime1 = this.timeFormat(currentTime, "getMonth");
let mTime2 = this.timeFormat(nextTime, "getMonth");
const resStr1 = yTime1 + "-" + mTime1;
const resStr2 = yTime2 + "-" + mTime2;
// 去重处理
const yList = Array.from(new Set([resStr1, resStr2]));
this.setData({
years: yList,
yList,
});
console.log("yList:", yList);
},
// 获取日期
getDay(currentTime, nextTime) {
let dTime1 = this.timeFormat(currentTime, "getDate");
let dTime2 = this.timeFormat(nextTime, "getDate");
// 去重处理
const dList = Array.from(new Set([dTime1, dTime2]));
this.setData({
dList,
days: dList,
});
console.log("dList:", dList);
},
// 获取小时列表,整点需要处理
getHour(currentTime, nextTime) {
let workTime = currentTime;
let hList1 = [],
hList2 = [],
hList = [];
// 第一天的日期
const day1 = this.timeFormat(currentTime, "getDate");
while (workTime <= nextTime) {
let H = this.timeFormat(workTime, "getHours"); //获取当前小时数(0-23)
// 第二天的日期
const day2 = this.timeFormat(workTime, "getDate");
if (day1 == day2) {
hList1.push(H);
} else {
hList2.push(H);
}
hList.push(H);
workTime = workTime + 3600000;
}
// 获取分钟
let M = this.timeFormat(currentTime, "getMinutes"); //获取当前分钟数(0-59)
// 判断如果是整点,就去掉最后一个小时
if (M == "00") {
hList2.splice(hList2.length - 1);
}
this.setData({
hList1,
hList2,
hList,
hours: hList1,
});
console.log("hList:", [hList1, hList2]);
},
// 获取分钟列表
getMinute(currentTime, nextTime) {
let workTime = currentTime;
let mList1 = [],
mList2 = [],
mList3 = [];
while (workTime <= nextTime) {
// 获取小时
let H = this.timeFormat(workTime, "getHours"); //获取当前小时数(0-23)
// 获取分钟
let M = this.timeFormat(workTime, "getMinutes"); //获取当前分钟数(0-59)
if (H == this.data.hList[0]) {
// 第一个小时
mList1.push(M);
} else if (
H == this.data.hList[this.data.hList.length - 1] &&
M != "00"
) {
//最后一个小时(不是整点,不满一个小时)
mList2.push(M);
} else if (
H == this.data.hList[this.data.hList.length - 1] &&
M == "00"
) {
//最后一个小时(整点,满一个小时)
mList2.push(M);
}
workTime = workTime + 60000;
}
// 获取满一个小时的分钟数
for (let i = 0; i < 60; i++) {
const M = i > 9 ? i : "0" + i;
mList3.push(M);
}
this.setData({
mList1,
mList2,
mList3,
minutes: mList1,
});
console.log("mList:", [mList1, mList2, mList3]);
},
//时间生成并加0处理
timeFormat(time, type) {
let resTime = new Date(time)[type]();
// 获取月份的要+1
resTime = type == "getMonth" ? resTime + 1 : resTime;
// 小于10,前面加0
resTime = resTime > 9 ? resTime : "0" + resTime;
return resTime;
},
// 处理最后生成的pickerTime字符串
handleTimeRegion() {
const data = this.data.pickerTime;
const y = this.data.years[data[0]];
const d = this.data.days[data[1]];
const h = this.data.hours[data[2]];
const m = this.data.minutes[data[3]];
const timeRegion = y + "-" + d + " " + h + ":" + m + ":" + "00";
this.setData({
timeRegion,
});
},
// 取消
onCancel() {
const obj = {
timeRegion: "",
isPicker: false,
};
this.triggerEvent("onselect", obj);
},
// 确认
onChecking() {
const obj = {
timeRegion: this.data.timeRegion,
isPicker: true,
};
this.triggerEvent("onselect", obj);
},
},
});
json文件
{
"component": true,
"usingComponents": {}
}
wxml文件
<!-- components/pickerTime/pickerTime.wxml -->
<!-- 选择未来24小时之内的时间点,打开默认选当前时间一个小时后的时间 -->
<view class="picker-body">
<view class="show-time">选定的时间:{{timeRegion}}</view>
<picker-view indicator-style="height: 40px;" style="width: 100%; height: 160px;" value="{{pickerTime}}" bindchange="bindChange">
<picker-view-column>
<view wx:for="{{years}}" wx:key="item" style="line-height: 40px; text-align: center;">
{{item}}
</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{days}}" wx:key="item" style="line-height: 40px; text-align: center;">
{{item}}日
</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{hours}}" wx:key="item" style="line-height: 40px; text-align: center;">
{{item}}时
</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{minutes}}" wx:key="item" style="line-height: 40px; text-align: center;">
{{item}}分
</view>
</picker-view-column>
</picker-view>
<view class="btnBox">
<button class='myBtn cancel' style="width: 40%;" bindtap="onCancel">取消</button>
<button class='myBtn checking' style="width: 40%;" bindtap="onChecking">完 成</button>
</view>
</view>
wxss文件
/* components/pickerTime/pickerTime.wxss */
.btnBox {
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
background-color: #fff;
margin-top: 20rpx;
}
.myBtn {
color: #fff;
font-weight: normal;
border-radius: 50rpx;
margin: 0;
}
.cancel {
background-color: #fff;
color: #444;
border: 2rpx solid #a5a3a3;
}
.checking {
background-color: #3f74ee;
}
.picker-body {
width: 100%;
height: 400rpx;
position: fixed;
bottom: 300rpx;
background-color: #fff;
border-top: 2rpx solid #999;
z-index: 999;
}
.show-time {
width: 100%;
height: 100rpx;
text-align: center;
line-height: 100rpx;
color: #333;
}
页面引用
//json
{
"usingComponents": {
"pickerTime":"../../../components/pickerTime/pickerTime"
},
}
//wxml
<!-- 选择时间 -->
<pickerTime bind:onselect="onselect" wx:if="{{openPicker}}" />
//js
data: {
openPicker: true,//打开组件
timeRegion:'',//选定的时间字符串
},
// 确认时间
onselect({ detail }) {
this.setData({
timeRegion: detail.timeRegion || this.data.timeRegion,
openPicker: false,
});
},