问题的背景
在之前做Web项目的时候,开始时间和结束时间,只有2个要求:
1、开始时间必须小于等于结束时间,不能超过当前时间。
2、结束时间必须大于等于开始时间,不能超过当前时间。
由于开始时间不大于结束时间,“开始时间不能超过当前时间,没有必要设置”。
最近的项目,又多了第3个条件。
3、开始时间和结束时间的范围最大间隔为30天(1个月)。
日历组件方面,一直用的是My97,官网是http://my97.net/dp/demo/index.htm
方法1:自己根据官网琢磨的。
根据官网的例子,有以下第1种看上去正确的方法:
  1. <span>开始日期</span><input name="startTime" id="startTime" onfocus="startTimeFocus();" class="input-text Wdate" style="width:200px" >
  2. <span>结束日期</span><input name="endTime" id="endTime" onfocus="endTimeFocus();" class="input-text Wdate"style="width:200px" >

  1. function startTimeFocus() {
  2. return WdatePicker({
  3. skin : 'whyGreen',
  4. minDate:'#F{$dp.$D(\'endTime\',{d:-30});}',
  5. maxDate : '#F{$dp.$D(\'endTime\')||\'%y-%M-%d\'}',
  6. doubleCalendar:true,
  7. dateFmt:'yyyy-MM-dd'
  8. });
  9. }
  10.  
  11. function endTimeFocus() {
  12. return WdatePicker({
  13. skin : 'whyGreen',
  14. minDate:'#F{$dp.$D(\'startTime\')}',
  15. maxDate : '#F{$dp.$D(\'startTime\',{d:30})||\'%y-%M-%d\'}',
  16. doubleCalendar:true,
  17. dateFmt:'yyyy-MM-dd'
  18. });
  19. }

但是,在我去测试的时候发现一个问题,“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使用自定义函数。
  1. function endTimeFocus() {
  2. return WdatePicker({
  3. skin : 'whyGreen',
  4. minDate:'#F{$dp.$D(\'startTime\')}',
  5. //maxDate : '#F{$dp.$D(\'startTime\',{d:30})||\'%y-%M-%d\'}',
  6. maxDate:getMaxDate(),
  7. doubleCalendar:true,
  8. dateFmt:'yyyy-MM-dd'
  9. });
  10. }
  11. //获得最大时间
  12. function getMaxDate(){
  13. var clock=currentTime();
  14. var dt;
  15. var times=0;
  16. dt=$("#startTime").val();
  17. if(dt!=''){
  18. times =Date.parse(dt.replace(/-/g,'/'))+30*24*60*60*1000;//时间间隔为30天
  19.  
  20. if(times-Date.parse(clock.replace(/-/g,'/'))<0){
  21. var d1 = new Date(times);
  22. var year = d1.getFullYear();
  23. var month = d1.getMonth() + 1; //月份以0开头
  24. var day = d1.getDate();
  25.  
  26. var hh = d1.getHours();
  27. var mm = d1.getMinutes();
  28.  
  29. var clock = year + "-";
  30.  
  31. if (month < 10) clock += "0";
  32. clock += month + "-";
  33.  
  34. if (day < 10) clock += "0";
  35. clock += day + " ";
  36.  
  37. if (hh < 10) clock += "0";
  38. clock += hh + ":";
  39.  
  40. if (mm < 10) clock += '0';
  41. clock += mm;
  42.  
  43. }
  44. }
  45. return clock;
  46. }
  47.  
  48. //当前时间
  49. function currentTime() {
  50. var now = new Date();
  51.  
  52. var year = now.getFullYear();
  53. var month = now.getMonth() + 1;
  54. var day = now.getDate();
  55.  
  56. var hh = now.getHours();
  57. var mm = now.getMinutes();
  58.  
  59. var clock = year + "-";
  60.  
  61. if (month < 10) clock += "0";
  62. clock += month + "-";
  63.  
  64. if (day < 10) clock += "0";
  65. clock += day + " ";
  66.  
  67. if (hh < 10) clock += "0";
  68. clock += hh + ":";
  69.  
  70. if (mm < 10) clock += '0';
  71. clock += mm;
  72. return (clock);
  73. }

方法3:自定义maxDate,封装成组件。
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>My97DatePicker示例</title>
  6. <script type="text/javascript" src="../libs/My97DatePicker/WdatePicker.js"></script>
  7. <script type="text/javascript" src="picker1.js"></script>
  8. <link type="text/css" href="97.css" rel="stylesheet" media="all" />
  9. </head>
  10.  
  11. <body>
  12.  
  13. <h1>My97DatePicker代码演示</h1>
  14.  
  15. <article class="demo">
  16. <h2>1.两日期时间相差30天,不超过当前日期,控件Picker1</h2>
  17. 开始时间:<input type="text" class="date_input" id="datepicker1"/>
  18. 结束时间:<input type="text" class="date_input" id="datepicker2"/>
  19. </article>
  20.  
  21. <article class="demo">
  22. <h2>1.两日期时间相差15天,不超过当前日期,控件Picker1</h2>
  23. 开始时间:<input type="text" class="date_input" id="datepicker3"/>
  24. 结束时间:<input type="text" class="date_input" id="datepicker4"/>
  25. </article>
  26.  
  27. <script type="text/javascript">
  28. var picker1 = new Picker1("datepicker1","datepicker2",30);
  29. picker1.init();
  30. var picker2 = new Picker1("datepicker3","datepicker4",15);
  31. picker2.init();
  32. </script>
  33.  
  34. </body>
  35. </html>

picker1.js
  1. /**
  2. * author:ls
  3. * email:liusaint@gmail.com
  4. * date:2016年1月2日
  5. */
  6. //IE9以下不能使用bind的处理。
  7. if (!Function.prototype.bind) {
  8. 	Function.prototype.bind = function (oThis) {
  9. 		if (typeof this !== "function") {
  10. 			throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
  11. 		}
  12. 		var aArgs = Array.prototype.slice.call(arguments, 1),
  13. 		fToBind = this,
  14. 		fNOP = function () {},
  15. 		fBound = function () {
  16. 			return fToBind.apply(this instanceof fNOP && oThis ? this: oThis,
  17. 				aArgs.concat(Array.prototype.slice.call(arguments)));
  18. 		};
  19. 		fNOP.prototype = this.prototype;
  20. 		fBound.prototype = new fNOP();
  21. 		return fBound;
  22. 	};
  23. }
  24. function Picker1(startEle,endEle,day){
  25. 	this.md = new Date();
  26. 	this.startEle = startEle;
  27. 	this.endEle = endEle;
  28. 	this.day = -day;
  29. }
  30. Picker1.prototype = {
  31. 	init:function(){
  32. 		//初始化控件。给开始日期输入框和结束的输入框绑定事件。传入合理的参数。注意this。
  33. 		var that = this;
  34. 		document.getElementById(this.startEle).onfocus = function(){
  35. 			that.picker1rule(this);
  36. 		}
  37. 		document.getElementById(this.endEle).onfocus = function(){
  38. 			that.picker2rule(this);
  39. 		}
  40. 	},
  41. 	picker1rule:function(ele){
  42. 		//开始日期的输入框的规则
  43. 		var pickedfunBind = this.pickedFunc.bind(ele,this);
  44. 		var onclearedBind = this.clearedFun.bind({},this);
  45. 		WdatePicker({maxDate:'#F{$dp.$D(\''+this.endEle+'\')||\'new Date()\'}',minDate:'#F{$dp.$D(\''+this.endEle+'\',{d:'+this.day+'})}',onpicked:pickedfunBind,oncleared:onclearedBind})
  46. 	},
  47. 	picker2rule:function(ele){
  48. 		// console.log(this.md,this,"in picker2rule");
  49. 		WdatePicker({el:ele,minDate:'#F{$dp.$D(\''+this.startEle+'\')}',maxDate:this.md})
  50. 	},
  51. 	pickedFunc:function(that){
  52. 		//开始日期的输入框的规则,onpicked时候的动作
  53. 		var Y=$dp.cal.getP('y');
  54. 		var M=$dp.cal.getP('M');
  55. 		var D=$dp.cal.getP('d');
  56. 		// var choosedDateArr = document.getElementById(that.startEle).value.split("-");
  57. 		// var Y=choosedDateArr[0];
  58. 		// var M=choosedDateArr[1];
  59. 		// var D=choosedDateArr[2];
  60. 		M=parseInt(M,10)-1;
  61. 		D=parseInt(D,10) - that.day; //超过30天,也能自动处理。
  62. 		var d = new Date()
  63. 		d.setFullYear(Y,M,D) //设置时间
  64. 		var nowDate=new Date(); 
  65. 		//跟现在的时间比较,如果算出来的值大于现在时间,修改全局变量md为现在时间。否则为算出来的时间。
  66. 		if(nowDate<=d){
  67. 			that.md=nowDate;
  68. 		}else{
  69. 			var month=d.getMonth()+1; //月份的范围是(0到11);
  70. 			that.md=d.getFullYear()+"-"+month+"-"+d.getDate(); //直接把d给过去会有问题,所以拼成字符串发过去
  71. 		}
  72. 	},
  73. 	clearedFun:function(that){
  74. 		//开始日期的输入框的规则,onpicked时候的动作oncleared
  75. 		that.md=new Date();
  76. 		// console.log(that.md,that,'in clear');
  77. 	}
  78. };
结束语:
1、3个条件,同时满足,官网的例子不够用了,需要手动写maxDate自定义函数。
自己嫌麻烦,就从网上找到了2种解法,亲自尝试是可行的,目前没有发现bug。
2、网上有2种正确的解决,但是他们并没有去“还原解法的过程”,为什么要这么做?
在正确解法之前,是不是走了一些“弯路”,遇到一些坑。
因此,我把自己遇到的坑的经历,分享出来。
3、我们在学习技术和知识的时候,过程也很重要,尤其是“思考的过程”,“从错误走向正确的过程”。
同样的道理,我们在学习数学的时候,只知道定理是很不足的,还需要知道“推理的过程”。
知道“推理的过程”,仍然是不够的。
那个数学家,某某某,他是怎么发现和得出推理过程的呢?
参考资料

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

  1. [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)

    /// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...

  2. My97DatePicker 日期控制,开始时间不能>结束时间,结束时间不能<开始时间

    <li>日期: <input type="text" style="margin-top: 5px;" value="${begin ...

  3. myDate97 设置开始时间和结束时间

      myDate97 设置开始时间和结束时间 CreationTime--2018年8月28日16点46分 Author:Marydon 1.简单示例 第一步:引入My97DatePicker/Wda ...

  4. bootstrap-datetimepicker 进一步跟进~~~开始时间和结束时间的样式显示

    上次简单介绍了一下:05.LoT.UI 前后台通用框架分解系列之——漂亮的时间选择器(http://www.cnblogs.com/dunitian/p/5524019.html) 这次深入再介绍一下 ...

  5. c# 获取 本周、本月、本季度、本年 的开始时间或结束时间

    #region 获取 本周.本月.本季度.本年 的开始时间或结束时间 /// <summary> /// 获取结束时间 /// </summary> /// <param ...

  6. java获取本月开始时间和结束时间、上个月第一天和最后一天的时间以及当前日期往前推一周、一个月

    import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.uti ...

  7. easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大

    easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大 >>>>>>>>>>> ...

  8. project 2013 设置工期为1个工作日,但开始时间与结束时间不是同一天

    1.问题描述 project2013在工期栏输入  1  ,在开始时间结束时间点自动安排,就会出现如下情况,会被误认为是两天 2.问题解决 文件-->选项-->常规-->日期格式选择 ...

  9. C# 根据第几周和季度 获取开始时间和结束时间

    /// <summary> /// 根据第几周 获取开始时间和结束时间 /// </summary> /// <param name="week"&g ...

随机推荐

  1. c# 多线程之-- System.Threading Timer的使用

    作用:每隔多久去执行线程里的方法. class ThreadTimerDemo { static void Main(string[] args) { // Create an AutoResetEv ...

  2. .Net Core+Vue.js+ElementUI 实现前后端分离

    .Net Core+Vue.js+ElementUI 实现前后端分离 Tags: Vue 架构 前端采用:Vue.js.Element-UI.axios 后端采用:.Net Core Mvc 本项目是 ...

  3. 给UIScrollView添加category实现UIScrollView的轮播效果

    给UIScrollView添加category实现UIScrollView的轮播效果 大家都知道,要给category添加属性是必须通过runtime来实现的,本教程中给UIScrollView添加c ...

  4. AT89S52之串行异步通信笔记

    SRF 中断入口地址 中断源 外中断 外部中断0 INT0(P3.2) 外部中断1 INT1(P3.3) 电平方式触发 低电平 脉冲方式触发 脉冲后延的负跳 内中断 定时中断 串行中断 中断允许控制寄 ...

  5. [EffectiveC++]item27:尽量少做转型动作

  6. for/while 循环全部执行完,, 中途不会停下!!中途不会停下!!中途不会停下!!! 中途不会停下!!!!!

    对于这样一个在for 里面的, 他会从开始到最后走走一遍,然后再回到开始, 而不是在里面有两个操作,全部操作完第一个再往下走, 这个和我的学习方法似乎一样,真的要全局来一遍,再从新来一遍回顾问题 下面 ...

  7. 021.15 IO流 其他流

    IO包中的其他类操作基本数据类型:DataInputStream与DataOutputStream操作字节数组:ByteArrayInputStream与ByteArrayOutputStream操作 ...

  8. oracle查看用户属于哪个表空间

    select username,default_tablespace from dba_users  where username='用户名';

  9. 1.4 Installation and Setup(安装和设置)

    1.4 Installation and Setup(安装和设置) 这里我们用Anaconda发行版作为Python的使用环境,推荐安装Python3.6,本书就是用Python3.6代码写成的.(译 ...

  10. 超链接<a>标签用法

    1.a标签点击事件 1>1a href="javascript:js_method();" 这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问题,而且 ...