My97DatePicker:开始时间和结束时间的最大间隔为1个月30天,并且不大于当前时间(3种方法)...

贡英华
2023-12-01
问题的背景
在之前做Web项目的时候,开始时间和结束时间,只有2个要求:
1、开始时间必须小于等于结束时间,不能超过当前时间。
2、结束时间必须大于等于开始时间,不能超过当前时间。
由于开始时间不大于结束时间,“开始时间不能超过当前时间,没有必要设置”。

最近的项目,又多了第3个条件。
3、开始时间和结束时间的范围最大间隔为30天(1个月)。
日历组件方面,一直用的是My97,官网是 http://my97.net/dp/demo/index.htm

方法1:自己根据官网琢磨的。
根据官网的例子,有以下第1种看上去正确的方法:
<span>开始日期</span><input name="startTime" id="startTime" οnfοcus="startTimeFocus();"  class="input-text Wdate" style="width:200px" >  
  		<span>结束日期</span><input name="endTime" id="endTime" οnfοcus="endTimeFocus();" class="input-text Wdate"style="width:200px" >  

function startTimeFocus() {
	return WdatePicker({
		skin : 'whyGreen',
		minDate:'#F{$dp.$D(\'endTime\',{d:-30});}',
		maxDate : '#F{$dp.$D(\'endTime\')||\'%y-%M-%d\'}',
		doubleCalendar:true,
		dateFmt:'yyyy-MM-dd'
	});
}

function endTimeFocus() {
	return WdatePicker({
		skin : 'whyGreen',
		minDate:'#F{$dp.$D(\'startTime\')}',
		maxDate : '#F{$dp.$D(\'startTime\',{d:30})||\'%y-%M-%d\'}',
		doubleCalendar:true, 
		dateFmt:'yyyy-MM-dd'
	});
}

但是,在我去测试的时候发现一个问题,“maxDate结束时间”可能会超过“当前时间”。
然后再看了官网的1个例子:
#F{$dp.$D(\'d4332\',{M:-3,d:-2}) || $dp.$DV(\'2020-4-3\',{M:-3,d:-2})}
表示当 d4332 为空时, 采用 $dp.$DV(\'2020-4-3\',{M:-3,d:-2})} 的值作为最大值。
这句话的意思,不就是说“||”,本质还是“逻辑或”,与程序设计中的“||”是同样的意思。
找遍官网的例子,没有逻辑与。或者自己想当然尝试“逻辑与&&”,是有问题的。

开始时间为什么不会超过呢?
#F{$dp.$D(\'endTime\')||\'%y-%M-%d\'}
因为是“逻辑||”,要么是“结束时间,结束时间不应该超过当前时间”,或者是“结束时间为空,也不超过当前时间”。

结论:完全使用官网的“函数”和“表达式”,不能实现满足第3个条件的功能。
需要再想点其它办法。

方法2:maxDate使用自定义函数。
function endTimeFocus() {
	return WdatePicker({
		skin : 'whyGreen',
		minDate:'#F{$dp.$D(\'startTime\')}',
		//maxDate : '#F{$dp.$D(\'startTime\',{d:30})||\'%y-%M-%d\'}',
		maxDate:getMaxDate(),
		doubleCalendar:true, 
		dateFmt:'yyyy-MM-dd'
	});
}
//获得最大时间
function getMaxDate(){
	var clock=currentTime();  
    var dt;  
    var times=0;  
    dt=$("#startTime").val();  
    if(dt!=''){  
        times =Date.parse(dt.replace(/-/g,'/'))+30*24*60*60*1000;//时间间隔为30天  
      
        if(times-Date.parse(clock.replace(/-/g,'/'))<0){  
            var d1 = new Date(times);  
            var year = d1.getFullYear();         
            var month = d1.getMonth() + 1;    //月份以0开头   
            var day = d1.getDate();             
  
            var hh = d1.getHours();              
            var mm = d1.getMinutes();            
  
            var clock = year + "-";  
  
            if (month < 10) clock += "0";  
            clock += month + "-";  
  
            if (day < 10) clock += "0";  
            clock += day + " ";  
  
            if (hh < 10) clock += "0";  
            clock += hh + ":";  
  
            if (mm < 10) clock += '0';  
            clock += mm;  
                          
        }  
    }  
    return clock;  
}

//当前时间
function currentTime() {  
    var now = new Date();  
          
    var year = now.getFullYear();         
    var month = now.getMonth() + 1;       
    var day = now.getDate();             

    var hh = now.getHours();              
    var mm = now.getMinutes();            

    var clock = year + "-";  

    if (month < 10)  clock += "0";  
    clock += month + "-";  

    if (day < 10) clock += "0";  
    clock += day + " ";  

    if (hh < 10)  clock += "0";  
    clock += hh + ":";  

    if (mm < 10) clock += '0';  
    clock += mm;  
    return (clock);  
}  


方法3:自定义maxDate,封装成组件。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>My97DatePicker示例</title>
	<script type="text/javascript" src="../libs/My97DatePicker/WdatePicker.js"></script>
	<script type="text/javascript" src="picker1.js"></script>
	<link type="text/css" href="97.css" rel="stylesheet" media="all" />
</head>

<body>

	<h1>My97DatePicker代码演示</h1>

	<article class="demo">
		<h2>1.两日期时间相差30天,不超过当前日期,控件Picker1</h2>
		开始时间:<input type="text" class="date_input" id="datepicker1"/>
		结束时间:<input type="text" class="date_input" id="datepicker2"/>
	</article>


	<article class="demo">
		<h2>1.两日期时间相差15天,不超过当前日期,控件Picker1</h2>
		开始时间:<input type="text" class="date_input" id="datepicker3"/>
		结束时间:<input type="text" class="date_input" id="datepicker4"/>
	</article>

	<script type="text/javascript">
		var picker1 = new Picker1("datepicker1","datepicker2",30);
		picker1.init();
		var picker2 = new Picker1("datepicker3","datepicker4",15);
		picker2.init();
	</script>


</body>
</html>


picker1.js
/**
* author:ls
* email:liusaint@gmail.com
* date:2016年1月2日
*/

//IE9以下不能使用bind的处理。
if (!Function.prototype.bind) { 
	Function.prototype.bind = function (oThis) { 
		if (typeof this !== "function") { 
			throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 
		} 
		var aArgs = Array.prototype.slice.call(arguments, 1), 
		fToBind = this, 
		fNOP = function () {}, 
		fBound = function () { 
			return fToBind.apply(this instanceof fNOP && oThis ? this: oThis, 
				aArgs.concat(Array.prototype.slice.call(arguments))); 
		}; 
		fNOP.prototype = this.prototype; 
		fBound.prototype = new fNOP(); 
		return fBound; 
	}; 
}

function Picker1(startEle,endEle,day){
	this.md = new Date();
	this.startEle = startEle;
	this.endEle = endEle;
	this.day = -day;
}

Picker1.prototype = {
	init:function(){
		//初始化控件。给开始日期输入框和结束的输入框绑定事件。传入合理的参数。注意this。
		var that = this;
		document.getElementById(this.startEle).onfocus = function(){
			that.picker1rule(this);
		}
		document.getElementById(this.endEle).onfocus = function(){
			that.picker2rule(this);
		}
	},
	picker1rule:function(ele){
		//开始日期的输入框的规则

		var pickedfunBind = this.pickedFunc.bind(ele,this);
		var onclearedBind = this.clearedFun.bind({},this);

		WdatePicker({maxDate:'#F{$dp.$D(\''+this.endEle+'\')||\'new Date()\'}',minDate:'#F{$dp.$D(\''+this.endEle+'\',{d:'+this.day+'})}',onpicked:pickedfunBind,oncleared:onclearedBind})
	},
	picker2rule:function(ele){
		// console.log(this.md,this,"in picker2rule");
		WdatePicker({el:ele,minDate:'#F{$dp.$D(\''+this.startEle+'\')}',maxDate:this.md})
	},
	pickedFunc:function(that){
		//开始日期的输入框的规则,onpicked时候的动作
		var Y=$dp.cal.getP('y');
		var M=$dp.cal.getP('M');
		var D=$dp.cal.getP('d');

		// var choosedDateArr = document.getElementById(that.startEle).value.split("-");
		// var Y=choosedDateArr[0];
		// var M=choosedDateArr[1];
		// var D=choosedDateArr[2];

		M=parseInt(M,10)-1;
		D=parseInt(D,10) - that.day; //超过30天,也能自动处理。
		var d = new Date()
		d.setFullYear(Y,M,D) //设置时间

		var nowDate=new Date(); 
		//跟现在的时间比较,如果算出来的值大于现在时间,修改全局变量md为现在时间。否则为算出来的时间。
		if(nowDate<=d){
			that.md=nowDate;
		}else{
			var month=d.getMonth()+1; //月份的范围是(0到11);
			that.md=d.getFullYear()+"-"+month+"-"+d.getDate(); //直接把d给过去会有问题,所以拼成字符串发过去
		}
	},
	clearedFun:function(that){
		//开始日期的输入框的规则,onpicked时候的动作oncleared
		that.md=new Date();
		// console.log(that.md,that,'in clear');
	}
};



结束语:
1、3个条件,同时满足,官网的例子不够用了,需要手动写maxDate自定义函数。
自己嫌麻烦,就从网上找到了2种解法,亲自尝试是可行的,目前没有发现bug。
2、网上有2种正确的解决,但是他们并没有去“还原解法的过程”,为什么要这么做?
在正确解法之前,是不是走了一些“弯路”,遇到一些坑。
因此,我把自己遇到的坑的经历,分享出来。
3、我们在学习技术和知识的时候,过程也很重要,尤其是“思考的过程”,“从错误走向正确的过程”。
同样的道理,我们在学习数学的时候,只知道定理是很不足的,还需要知道“推理的过程”。
知道“推理的过程”,仍然是不够的。
那个数学家,某某某,他是怎么发现和得出推理过程的呢?

参考资料

转载于:https://www.cnblogs.com/qitian1/p/6462202.html

 类似资料: