微信小程序自定义picker年月日时分秒选择器组件

功能:
年月日时分秒,固定选择范围
效果:


效果图.png

自定义组件实现:
utils/datePicker.js

class BaseInfo {
  constructor() {
    this.newDate = new Date();
  }
  withData(param) {
    return parseInt(param) < 10 ? '0' + param : '' + param;
  }
  getLoopArray(start, end) {
    var start = start || 0;
    var end = end || 0;
    var array = [];
    for (var i = start; i <= end; i++) {
      array.push(this.withData(i));
    }
    return array;
  }
  formatArr(dateString) {
    return [...dateString.split(' ')[0].split('-'), ...dateString.split(' ')[1].split(':')]
    //return [...dateString.split(' ')[0].split('-')]
  }
  beforeDateArr(disYear) {
    /*
     * 处理前
     * 获取当前时间
     */
    let year = this.newDate.getFullYear() - (disYear || 0)
    let month = this.newDate.getMonth() + 1
    let day = this.newDate.getDate()
    let hour = this.newDate.getHours()
    let minute = this.newDate.getMinutes()
    return [year, month, day, hour, minute]
  }
  afterDateArr() {
    /*
     * 处理后
     * 获取当前时间
     */
    let year = this.withData(this.newDate.getFullYear())
    let mont = this.withData(this.newDate.getMonth() + 1)
    let date = this.withData(this.newDate.getDate())
    let hour = this.withData(this.newDate.getHours())
    let minu = this.withData(this.newDate.getMinutes())
    return [year, mont, date, hour, minu];
  }
}

// 实现
class dateTimePicker extends BaseInfo {
  constructor(startDate, endDate, defaultDate) {
    super();
    this.dateTimeArray = null
    this.dateTime = null
    this.startDate = super.formatArr(startDate); // 开始时间
    this.endDate = endDate ? super.formatArr(endDate) : super.afterDateArr(); // 结束时间
    this.defaultDate = defaultDate ? super.formatArr(defaultDate) : this.startDate;
  }
  setValue(obj) {
    for (let key in obj) {
      this[key] = obj[key]
    }
  }
  /* 获取当前切换选择的日期值*/
  getCurDateInfo() {
    return this.dateTime && this.dateTimeArray ? {
      year: this.dateTimeArray[0][this.dateTime[0]],
      month: this.dateTimeArray[1][this.dateTime[1]],
      day: this.dateTimeArray[2][this.dateTime[2]],
      hour: this.dateTimeArray[3][this.dateTime[3]],
      second: this.dateTimeArray[4][this.dateTime[4]],
    } : {}
  }
  /* 获取月数组*/
  getMonths() {
    let array = []
    const year = (this.getCurDateInfo().year || this.defaultDate[0]).replace(/年/, '');
    if (this.startDate[0] == this.endDate[0]) {
      /* 
       * 开始的年和结束的年相同
       * 就取(开始月,结束月)
       */
      array = super.getLoopArray(parseInt(this.startDate[1]), parseInt(this.endDate[1]))
    } else {
      switch (year) {
        case this.startDate[0]:
          /* 开始年 */
          array = super.getLoopArray(parseInt(this.startDate[1]), 12)
          break;
        case this.endDate[0]:
          /* 结束年 */
          array = super.getLoopArray(1, parseInt(this.endDate[1]))
          break;
        default:
          array = super.getLoopArray(1, 12)
          break;
      }
    }

    return array;
  }
  /* 获取日数组*/
  getDays() {
    let array = []
    let lastDay = null
    const year = (this.getCurDateInfo().year || this.defaultDate[0]).replace(/年/, '');
    const month = (this.getCurDateInfo().month || this.defaultDate[1]).replace(/月/, '');
    const flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    switch (month) {
      case '01':
      case '03':
      case '05':
      case '07':
      case '08':
      case '10':
      case '12':
        lastDay = 31
        break;
      case '04':
      case '06':
      case '09':
      case '11':
        lastDay = 30
        break;
      case '02':
        lastDay = flag ? 29 : 28
        break;
      default:
        array = '月份格式不正确,请重新输入!'
    }
    const afterDateArr = super.afterDateArr()
    const _start = year == this.startDate[0] && month == this.startDate[1]
    const _end = year == this.endDate[0] && month == this.endDate[1]
    if (this.startDate[0] == this.endDate[0] && this.startDate[1] == this.endDate[1]) {
      /*
       * 开始的年和结束的年相同,开始月和结束月相同
       * 就取(开始日,结束日)
       */
      array = super.getLoopArray(parseInt(this.startDate[2]), parseInt(this.endDate[2]))
    } else {
      if (_start) { // 开始年月
        array = super.getLoopArray(parseInt(this.startDate[2]), lastDay)
      } else if (_end) { // 结束年月
        array = super.getLoopArray(1, parseInt(this.endDate[2]))
      } else {
        array = super.getLoopArray(1, lastDay)
      }
    }

    return array;
  }

  /* 获取小时数组*/
  getHours() {
    let array = []
    const year = (this.getCurDateInfo().year || this.defaultDate[0]).replace(/年/, '');
    const month = (this.getCurDateInfo().month || this.defaultDate[1]).replace(/月/, '');
    const day = (this.getCurDateInfo().day || this.defaultDate[2]).replace(/日/, '');
    const _start = year == this.startDate[0] && month == this.startDate[1] && day == this.startDate[2]
    const _end = year == this.endDate[0] && month == this.endDate[1] && day == this.endDate[2]
    const _equal = this.startDate[0] == this.endDate[0] && this.startDate[1] == this.endDate[1] && this.startDate[
      2] == this.endDate[2]
    if (_equal) {
      /*
       * 开始的年月日和结束的年月日都相同
       * 就取(开始小时,结束小时)
       */
      array = super.getLoopArray(parseInt(this.startDate[3]), parseInt(this.endDate[3]))
    } else {
      if (_start) { // 开始年月日
        array = super.getLoopArray(parseInt(this.startDate[3]), 23)
      } else if (_end) { // 结尾年月日
        array = super.getLoopArray(0, parseInt(this.endDate[3]))
      } else {
        array = super.getLoopArray(0, 23)
      }
    }
    return array;
  }
  /* 获取分钟数组*/
  getMinutes(years, months, days, hours) {
    let array = []
    const year = (this.getCurDateInfo().year || this.defaultDate[0]).replace(/年/, '');
    const month = (this.getCurDateInfo().month || this.defaultDate[1]).replace(/月/, '');
    const day = (this.getCurDateInfo().day || this.defaultDate[2]).replace(/日/, '');
    const hour = (this.getCurDateInfo().hour || this.defaultDate[3]).replace(/时/, '');
    const _start = year == this.startDate[0] && month == this.startDate[1] && day == this.startDate[2] && hour == this
      .startDate[3]
    const _end = year == this.endDate[0] && month == this.endDate[1] && day == this.endDate[2] && hour == this
      .endDate[3]
    const _equal = this.startDate[0] == this.endDate[0] && this.startDate[1] == this.endDate[1] && this.startDate[
      2] == this.endDate[2] && this.startDate[3] == this.endDate[3]
    if (_equal) {
      /*
       * 开始的年月日时和结束的年月日时都相同
       * 就取(开始小时,结束小时)
       */
      array = super.getLoopArray(parseInt(this.startDate[4]), parseInt(this.endDate[4]))
    } else {
      if (_start) { // 开始年月日
        array = super.getLoopArray(parseInt(this.startDate[4]), 59)
      } else if (_end) { // 结尾年月日
        array = super.getLoopArray(0, parseInt(this.endDate[4]))
      } else {
        array = super.getLoopArray(0, 59)
      }
    }
    return array;
  }
  /*  */
  dispatch(index) {
    let arr = []
    switch (index) {
      case 0:
        arr = super.getLoopArray(this.startDate[0], this.endDate[0]);
        break;
      case 1:
        arr = this.getMonths();
        break;
      case 2:
        arr = this.getDays();
        break;
      case 3:
        arr = this.getHours();
        break;
      case 4:
        arr = this.getMinutes();
        break;
      default:
        break;
    }
    return arr
  }

  /* 初始默认数据 */
  render() {
    const dateTime = []
    const dateTimeArray = [
      [],
      [],
      [],
      [],
      []
    ];
    /*年月日 时分秒*/
    for (let i = 0; i < dateTimeArray.length; i++) {
      dateTimeArray[i] = this.dispatch(i)
    }
    dateTimeArray.forEach((current, index) => { 
      const _index = current.indexOf(this.defaultDate[index])
      dateTime.push(_index == -1 ? 0 : _index);
    });

    return {
      dateTimeArray,
      dateTime
    }
  }
}

function newDateTimePicker(startDateTime, endDateTime, pText){
  let newDateTimePicker = new dateTimePicker(startDateTime, endDateTime, pText)
  return newDateTimePicker
}
module.exports = {
  newDateTimePicker: newDateTimePicker,
}

定义组件components/datePicker/datePicker.js

const App = getApp();
const dateTimePicker = require('../../../utils/datePicker.js')
Component({
  options: {
    addGlobalClass: true,
  },
  /**
   * 组件的属性列表
   */
  properties: {
    params: {
        type: Object,
        value:{
          placeholder: '请选择时间', 
          startDateTime: '', 
          endDateTime: '', 
          pText: ''
        }
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    dateTimeArray: null,
    dateTime: null,
    startDateTime: '',
    endDateTime: '',
    dateTimeWhole: '',
  },
  lifetimes: {
    attached: function () {
     this.setData({
        startDateTime: this.data.params.startDateTime,
        endDateTime: this.data.params.endDateTime
      })
      this.initData()
    }
  },
  pageLifetimes: {
    show: function() {
      this.setData({
        startDateTime: this.data.params.startDateTime,
        endDateTime: this.data.params.endDateTime
      })
      this.initData()
    },
    hide: function() {
      // 页面被隐藏
    },
    resize: function(size) {
      // 页面尺寸变化
    }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    initData(date) {
      // 获取完整的年月日 时分秒,以及默认显示的数组
      this.data.unit = ['年', '月', '日', '时', '分']
      this.data.dateTimePicker = dateTimePicker.newDateTimePicker(this.data.startDateTime, this.data.endDateTime, this.data.params.pText)
      let obj = this.data.dateTimePicker.render();
      let lastArray = obj.dateTimeArray;
      let lastTime = obj.dateTime;
      for (let i = 0; i < lastArray.length; i++) {
        lastArray[i] = lastArray[i].map(m => m + this.data.unit[i])
      }
      this.data.dateTimeArray = lastArray
      this.data.dateTime = lastTime
      this.setData({
        dateTimeArray: this.data.dateTimeArray,
        dateTime: this.data.dateTime
      })
    },
    changeDateTime(e) { 
      this.data.dateTime = e.detail.value
      const year = this.data.dateTimeArray[0][this.data.dateTime[0]].replace(/年/, '')
      const month = this.data.dateTimeArray[1][this.data.dateTime[1]].replace(/月/, '')
      const day = this.data.dateTimeArray[2][this.data.dateTime[2]].replace(/日/, '')
      // const hour = this.data.dateTimeArray[3][this.data.dateTime[3]].replace(/时/, '')
      // const minute = this.data.dateTimeArray[4][this.data.dateTime[4]].replace(/分/, '')
      // this.data.dateTimeWhole = `${year}-${month}-${day} ${hour}:${minute}`
      this.data.dateTimeWhole = `${year}-${month}-${day}`
      this.setData({
        dateTimeWhole: this.data.dateTimeWhole,
      })
      console.log(this.data.dateTimeWhole)
      this.triggerEvent('getDateString', this.data.dateTimeWhole)
    },
    changeDateTimeColumn(e) {
      const { column, value } = e.detail
      // this.$set(this.data.dateTime, column, value)
      let dateTimeTemp = 'dateTime['+column+']'
      this.setData({
        [dateTimeTemp]: value
      })
      this.data.dateTimePicker.setValue({ dateTimeArray: this.data.dateTimeArray, dateTime: this.data.dateTime })
      for (let i = 1; i < this.data.dateTime.length; i++) {
        if (column == i - 1) {
          for (let j = i; j < this.data.dateTime.length; j++) {
            // this.$set(this.data.dateTime, j, 0)
            let temp = 'dateTime['+j+']'
            this.setData({
              [temp]: 0
            })
          }
        }
        let arr = this.data.dateTimePicker.dispatch(i).map(m => m + this.data.unit[i])
        // this.$set(this.data.dateTimeArray, i, arr)
        let temp1 = 'dateTimeArray['+i+']'
        this.setData({
          [temp1]: arr
        })
      }
      this.setData({
        dateTimeArray: this.data.dateTimeArray,
        dateTime: this.data.dateTime
      })
    },


  }
})

components/datePicker/datePicker.wxml

<!--pages/components/datePicker/datePicker.wxml-->
<picker class="dateTimePicker"  mode="multiSelector" value="{{dateTime}}" bindchange="changeDateTime" bindcolumnchange="changeDateTimeColumn" range="{{dateTimeArray}}">
  <view class="tui-picker-detail wrap column-center">
    <text style="color:{{(dateTimeWhole||params.pText)?'#333333':'#999999'}}">{{dateTimeWhole || params.pText || params.placeholder ||"请选择时间"}}</text>
    <!-- <image class="icon" src="/static/mine/meArrowRight.png" mode=""></image> -->
  </view>
</picker>

components/datePicker/datePicker.wxss

/* pages/components/datePicker/datePicker.wxss */
.dateTimePicker {
  text-align: left;
  width: 300rpx;
}
.tui-picker-detail {
  border-radius: 10rpx;
  font-size: 32rpx;
}
.icon {
  width: 16rpx;
  height: 32rpx;
}

使用datePicker组件
index.json

{
  "usingComponents": {
    "datepicker": "../../pages/components/datePicker/datePicker"
  }
}

index.wxml

<datepicker params="{{params}}" bind:getDateString="changeDateTime1"></datepicker>

index.js

data: {
    params: { placeholder: '请选择时间', 
       startDateTime: '2022-03-30 00:00'), 
       endDateTime: '2023-01-30 00:00'),
       pText: '' //'2022-04-30 00:00'
   },
}
bindDateChange(e) {
    this.setData({
      ['parame.exceptNursingBeginTime']: e.detail
    });
  },
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容