小程序日期时间段选择

时间:2022-08-19 14:01:20

效果图:

小程序日期时间段选择小程序日期时间段选择

wxml:

<view>旅游时间:
      <text>{{checkInDate}}</text>
    </view>
    <view>
      <navigator url='/pages/calendar/calendar'>
        <button>时间选择</button>
      </navigator>
    </view>

js:

var Moment = require("../../utils/moment.js");
var DATE_LIST = [];
var DATE_YEAR = new Date().getFullYear()
var DATE_MONTH = new Date().getMonth() + 1
var DATE_DAY = new Date().getDate()
data: {
    checkInDate: ""
  }



  /**
 * 生命周期函数--监听页面显示
 */
  onShow: function () {
    let getDate = wx.getStorageSync("ROOM_SOURCE_DATE");
    this.setData({
      checkInDate: getDate.checkInDate
    })
  },

utils:

var Moment = function (date) {
  var date;
  if (date)
    this.date = new Date(date);
  else
    this.date = new Date();
  return this;
};
/**       
 * 对Date的扩展,将 Date 转化为指定格式的String       
 * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符       
 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)       
 * eg:       
 * "yyyy-MM-dd hh:mm:ss.S" ==> 2006-07-02 08:09:04.423    
 * "yyyy-M-d h:m:s.S" ==> 2006-7-2 8:9:4.18       
 * "yyyy-MM-dd E HH:mm:ss" ==> 2009-03-10 二 20:09:04       
 * "yyyy-MM-dd EE hh:mm:ss" ==> 2009-03-10 周二 08:09:04       
 * "yyyy-MM-dd EEE hh:mm:ss" ==> 2009-03-10 星期二 08:09:04  
 */
Moment.prototype.format = function (format) {
  var date = this.date;
  /*
      var r= /^(\d{4})-(\d{1,2})-(\d{1,2})$/; //正则表达式 匹配出生日期(简单匹配)     
      r.exec('1985-10-15');
      s1=RegExp.$1;s2=RegExp.$2;s3=RegExp.$3;//结果为1985 10 15
      */
  if (typeof date === 'string')
    date = this.parse(date);
  var o = {
    "M+": date.getMonth() + 1, //月份 
    "(d+|D+)": date.getDate(), //
    "(h+|H+)": date.getHours(), //小时 
    "m+": date.getMinutes(), //
    "s+": date.getSeconds(), //
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度 
    "S": date.getMilliseconds() //毫秒 
  };
  var week = {
    "0": "/u65e5",
    "1": "/u4e00",
    "2": "/u4e8c",
    "3": "/u4e09",
    "4": "/u56db",
    "5": "/u4e94",
    "6": "/u516d"
  };
  if (/(y+|Y+)/.test(format))
    format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  if (/(E+)/.test(format))
    format = format.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[date.getDay() + ""]);
  for (var k in o) {
    if (new RegExp("(" + k + ")").test(format))
      format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  }
  return format;
}

Moment.prototype.parse = function () {
  return this.date;
}
/**
 * 计算两个日期差差
 * return day
 */
Moment.prototype.differ = function (date) {
  var time1 = this.date.getTime();
  if (typeof date === 'string')
    date = new Date(date);
  var time1 = this.date.getTime();
  var time2 = date.getTime();
  var differ = Math.ceil((time1 - time2) / (1000 * 3600 * 24));//除不尽时,向上取整
  return differ;
}

Moment.prototype.add = function (num, optionType) {
  var date = this.date;
  if ('day' === optionType) {
    date.setDate(date.getDate() + num);
  }
  if ('month' === optionType) {
    date.setMonth(date.getMonth() + num);
  }
  if ('year' === optionType) {
    date.setFullYear(date.getFullYear() + num);
  }
  this.date = date;
  return this;
}

Moment.prototype.before = function (date) {
  return this.date.getTime() < new Date(date).getTime()
}
Moment.prototype.after = function (date) {
  return this.date.getTime() > date.getTime()
}

module.exports = function (date) {
  return new Moment(date);
}

calendar:

var Moment = require("../../utils/moment.js");
var DATE_LIST = [];
var DATE_YEAR = new Date().getFullYear();
var DATE_MONTH = new Date().getMonth() + 1;
var DATE_DAY = new Date().getDate();
Page({
  data: {
    maxMonth: 1, //最多渲染月数
    dateList: [],
    systemInfo: {},
    weekStr: ['', '', '', '', '', '', ''],
    checkInDate: Moment(new Date()).format('YYYY-MM-DD'),
    markcheckInDate: false, //标记开始时间是否已经选择
    sFtv: [
      {
        month: 1,
        day: 1,
        name: "元旦"
      },
      {
        month: 2,
        day: 14,
        name: "情人节"
      },
      {
        month: 3,
        day: 8,
        name: "妇女节"
      },
      {
        month: 3,
        day: 12,
        name: "植树节"
      },
      {
        month: 3,
        day: 15,
        name: "消费者权益日"
      },
      {
        month: 4,
        day: 1,
        name: "愚人节"
      },
      {
        month: 5,
        day: 1,
        name: "劳动节"
      },
      {
        month: 5,
        day: 4,
        name: "青年节"
      },
      {
        month: 5,
        day: 12,
        name: "护士节"
      },
      {
        month: 6,
        day: 1,
        name: "儿童节"
      },
      {
        month: 7,
        day: 1,
        name: "建党节"
      },
      {
        month: 8,
        day: 1,
        name: "建军节"
      },
      {
        month: 9,
        day: 10,
        name: "教师节"
      },
      {
        month: 9,
        day: 28,
        name: "孔子诞辰"
      },
      {
        month: 10,
        day: 1,
        name: "国庆节"
      },
      {
        month: 10,
        day: 6,
        name: "老人节"
      },
      {
        month: 10,
        day: 24,
        name: "联合国日"
      },
      {
        month: 12,
        day: 24,
        name: "平安夜"
      },
      {
        month: 12,
        day: 25,
        name: "圣诞节"
      }
    ]
  },
  onLoad: function (options) {
    // 页面初始化 options为页面跳转所带来的参数
    this.createDateListData();
    var _this = this;
    // 页面初始化 options为页面跳转所带来的参数

    var checkInDate = options.checkInDate ? options.checkInDate : Moment(new Date()).format('YYYY-MM-DD');
    wx.getSystemInfo({
      success: function (res) {
        _this.setData({ systemInfo: res, checkInDate: checkInDate });
      }
    })
  },
  onReady: function () {
    // 页面渲染完成
  },
  onShow: function () {
    this.selectDataMarkLine()
  },
  onHide: function () {
    // 页面隐藏
  },
  onUnload: function () {
    // 页面关闭
  },

  //选择的入住与离店时间段
  selectDataMarkLine: function () {
    let dateList = this.data.dateList;
    let { checkInDate } = wx.getStorageSync("ROOM_SOURCE_DATE");
    let curreInid = checkInDate.substr(0, 4) + "-" + (checkInDate.substr(5, 2) < 10 ? checkInDate.substr(6, 1) : checkInDate.substr(5, 2));//选择入住的id

    let dayIn = checkInDate.substr(8, 2) >= 10 ? checkInDate.substr(8, 2) : checkInDate.substr(9, 1);//选择入住的天id
    let monthIn = checkInDate.substr(5, 2) >= 10 ? checkInDate.substr(5, 2) : checkInDate.substr(6, 1);//选择入店的月id
    if (curreInid) {//入住与离店是当月的情况
      for (let i = 0; i < dateList.length; i++) {
        if (dateList[i].id == curreInid) {
          let days = dateList[i].days;
          for (let k = 0; k < days.length; k++) {
            if (days[k].day >= dayIn) {
              days[k].class = days[k].class + ' bgitem';
            }
            if (days[k].day == dayIn) {
              days[k].class = days[k].class + ' active';
              days[k].inday = true;
            }
          }
        }
      }
    } else {//跨月
      for (let j = 0; j < dateList.length; j++) {
        if (dateList[j].month == monthIn) {//入住的开始月份
          let days = dateList[j].days;
          for (let k = 0; k < days.length; k++) {

            if (days[k].day == dayIn) {
              days[k].class = days[k].class + ' active';
              days[k].inday = true;
            }
          }
        } else {//入住跨月月份
          if (dateList[j].month < monthOut && dateList[j].month > monthIn) {//离店中间的月份
            let days = dateList[j].days;
            for (let k = 0; k < days.length; k++) {
              days[k].class = days[k].class + ' bgitem';
            }
          } else if (dateList[j].month == monthOut) {//离店最后的月份
            let days = dateList[j].days;
            for (let k = 0; k < days.length; k++) {

            }
          }
        }
      }
    }
    this.setData({
      dateList: dateList
    })
  },

  createDateListData: function () {
    var dateList = [];
    var now = new Date();
    /*
      设置日期为 年-月-01,否则可能会出现跨月的问题
      比如:2017-01-31为now ,月份直接+1(now.setMonth(now.getMonth()+1)),则会直接跳到跳到2017-03-03月份.
        原因是由于2月份没有31号,顺推下去变成了了03-03
    */
    now = new Date(now.getFullYear(), now.getMonth(), 1);
    for (var i = 0; i < this.data.maxMonth; i++) {
      var momentDate = Moment(now).add(this.data.maxMonth - (this.data.maxMonth - i), 'month').date;
      var year = momentDate.getFullYear();
      var month = momentDate.getMonth() + 1;

      var days = [];
      var totalDay = this.getTotalDayByMonth(year, month);
      var week = this.getWeek(year, month, 1);
      //-week是为了使当月第一天的日期可以正确的显示到对应的周几位置上,比如星期三(week = 2),
      //则当月的1号是从列的第三个位置开始渲染的,前面会占用-2,-1,0的位置,从1开正常渲染
      for (var j = -week + 1; j <= totalDay; j++) {
        var tempWeek = -1;
        if (j > 0)
          tempWeek = this.getWeek(year, month, j);
        var clazz = '';
        if (tempWeek == 0 || tempWeek == 6)
          clazz = 'week'
        if (j < DATE_DAY && year == DATE_YEAR && month == DATE_MONTH)
          //当天之前的日期不可用
          clazz = 'unavailable ' + clazz;
        else
          clazz = '' + clazz
        days.push({ day: j, class: clazz })
      }
      var dateItem = {
        id: year + '-' + month,
        year: year,
        month: month,
        days: days
      }

      dateList.push(dateItem);
    }
    var sFtv = this.data.sFtv;
    for (let i = 0; i < dateList.length; i++) {//加入公历节日
      for (let k = 0; k < sFtv.length; k++) {
        if (dateList[i].month == sFtv[k].month) {
          let days = dateList[i].days;
          for (let j = 0; j < days.length; j++) {
            if (days[j].day == sFtv[k].day) {
              days[j].daytext = sFtv[k].name
            }
          }
        }
      }
    }
    this.setData({
      dateList: dateList
    });
    DATE_LIST = dateList;
  },

  /*
     * 获取月的总天数
     */
  getTotalDayByMonth: function (year, month) {
    month = parseInt(month, 10);
    var d = new Date(year, month, 0);
    return d.getDate();
  },
    /*
     * 获取月的第一天是星期几
     */
  getWeek: function (year, month, day) {
    var d = new Date(year, month - 1, day);
    return d.getDay();
  },
  /**
   * 点击日期事件
   */
  onPressDate: function (e) {
    var { year, month, day } = e.currentTarget.dataset;
    //当前选择的日期为同一个月并小于今天,或者点击了空白处(即day<0),不执行
    if ((day < DATE_DAY && month == DATE_MONTH) || day <= 0) return;

    var tempMonth = month;
    var tempDay = day;

    if (month < 10) tempMonth = '0' + month
    if (day < 10) tempDay = '0' + day

    var date = year + '-' + tempMonth + '-' + tempDay;


    this.setData({
      checkInDate: date,
      markcheckInDate: true,
      dateList: DATE_LIST.concat()
    });


    //设缓存,返回页面时,可在onShow时获取缓存起来的日期
    wx.setStorage({
      key: 'ROOM_SOURCE_DATE',
      data: {
        checkInDate: this.data.checkInDate
      }
    });
    wx.navigateBack({
      delta: 1, // 回退前 delta(默认为1) 页面
    });
    this.renderPressStyle(year, month, day);
  },
  renderPressStyle: function (year, month, day) {
    var dateList = this.data.dateList;
    //渲染点击样式
    for (var i = 0; i < dateList.length; i++) {
      var dateItem = dateList[i];
      var id = dateItem.id;
      if (id === year + '-' + month) {
        var days = dateItem.days;
        for (var j = 0; j < days.length; j++) {
          var tempDay = days[j].day;
          if (tempDay == day) {
            days[j].class = days[j].class + ' active';
            days[j].inday = true;
            break;
          }
        }
        break;
      }
    }
    this.setData({
      dateList: dateList
    });
  }
})
<view style="position:fixed;top:0;background:#F5F5F5;font-size: 30rpx; padding-top: 10rpx;padding-bottom: 10rpx;">
  <view class="layout-flex row" style="background-color: #F5F5F5;">
    <text class="date-week" style="width:{{systemInfo.windowWidth/7-10}}px;height:20px" wx:for="{{weekStr}}" wx:key="{{index}}">
                 <text wx:if="{{item !=='日' && item !=='六'}}">{{item}}</text>
    <text wx:if="{{item ==='日' || item ==='六'}}" class="week">{{item}}</text>
    </text>
  </view>
</view>
<view style="margin-top:50px"></view>
<view wx:for="{{dateList}}" wx:key="{{index}}" wx:for-item="dateItem" style="padding:30rpx 0">
  <view class="date-year-month" style="text-align: center;font-size:35rpx;">{{dateItem.year}}年{{dateItem.month}}月</view>
  <view class="layout-flex row" style="flex-wrap: wrap;margin-top:30rpx;">
    <view class="date-day {{item.day<=0?'bgwhite':item.class}}" style="width:{{systemInfo.windowWidth/7-10}}px;height:{{systemInfo.windowWidth/7}}px;" data-year="{{dateItem.year}}" data-month="{{dateItem.month}}" data-day="{{item.day}}" bindtap="onPressDate" wx:for="{{dateItem.days}}"
      wx:key="{{index}}">
      <view class='item-days'>
        <text style='font-size:28rpx;'>{{item.day>0?(item.daytext?item.daytext:item.day):''}}</text>
        <text style='font-size:30rpx;' wx:if="{{item.inday}}">入住</text>
        <!-- <text style='font-size:30rpx;' wx:if="{{item.outday}}">离店</text> -->
      </view>
    </view>
  </view>
</view>
/* pages/dateSelect/dateSelect.wxss */
.date-day{
    display: flex;
    padding:5px;
    text-align:center;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}
.date-day.bgitem{
  background-color: #d8ecf9;
}
.date-day.active{
    background: #099FDE;
    color:#FFF;
    
}
.date-day.unavailable{
    color:#aaa;
}

.date-week{
    display: flex;
    justify-content: center;
    align-content: center;
    margin:5px;
}
.week{
    color:#099FDE;
}
.row{
  display: flex;
  flex-direction: row;
}
 .item-days{
  display: flex;
  flex-direction:column;
  justify-content: center;
  align-items: center;
  font-size: 35rpx;
} 
.bgwhite{
  background-color: #fff;
}