JS 获取合同的起始时间与终止时间——日期增加自然月,年。

需求: 在线签订电子合同;

获取合同的起始时间与终止时间,以用户点击签约为起始时间,计算用户在页面中选择的合约生效时长(可选6个月、1年等等)并推算出终止时间;

实现难点: 可能存在大月小月以及平年闰年时二月的天数转换问题(例如:用户在2021年11月30号签约,选择合约生效时长为6个月,按我接到的需求这里应该设置终止时间为2022-02-28);(一、结束时间为合同到期前一天)
在这里插入图片描述
我用的ant-design-vue(v2版本的时间选择器)

setEndDate(time,b) {

		  if(!this.valueTime[0]){        //valueTime是一个时间数组,valueTime[0]是开始时间   valueTime[1]是结束时间
             this.$message.error('请选择日期')
          };

        let a = this.SetMonth(time, b);
        this.valueTime[1]=a;
        console.log(a);
    },
    SetMonth(date, monthNum){
        let date1= new Date(date)
        var day = date1.getDate();
        var month = date1.getMonth()+1;
        var year = date1.getFullYear();
        var days = new Date(year, month, 0);
        days = days.getDate(); //获取当前日期中的月的天数
        var year2 = year;
        var month2 = parseInt(month) + parseInt(monthNum);
        if (month2 > 12) {
            year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12));
            month2 = parseInt(month2) % 12;
            if(month2 == 0) { // 正好被12整除  12月
                month2 = 12;
                year2-- ;
            }
        }
        var days2 = new Date(year2, month2, 0);
        days2 = days2.getDate();

        let year2IsR = (year2 % 4 == 0 && year2 % 100 != 0 || year2 % 400==0);
        let yearIsR = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
        // debugger
        // 如果开始日期大月 31号 结束日期是小月
        if((month2 == 4 || month2 == 6 || month2 == 9 || month2 == 11) && day == 31) {
            day = 30;
        }
        if((day == 31 || day == 30 ) && month2 == 2) {
            // 判断 是否闰年
            if(year2IsR) {
                // day = 29;
                day = 30;
            } else {
            // day = 28;
            day = 29;
            }
        } else if(day == 29 && month2 == 2) {
            // day = 28;
            day = 29;
        }
        // debugger
        if (month2 < 10) {
            month2 = '0' + month2;
        }
        if (day < 10) {
            day = '0' + day;
        }
        var endDate = year2 + '-' + month2 + '-' + day;
        return this.GetDateStr(endDate, -1);
    },
    GetDateStr(dateStr,AddDayCount) {
       var dd = new Date(dateStr);
       dd.setDate(dd.getDate()+AddDayCount);//获取AddDayCount天后的日期
       var y = dd.getFullYear();
       var m = (dd.getMonth()+1)<10?"0"+(dd.getMonth()+1):(dd.getMonth()+1);//获取当前月份的日期,不足10补0
       var d = dd.getDate()<10?"0"+dd.getDate():dd.getDate();//获取当前几号,不足10补0
       return y+"-"+m+"-"+d;
    },

二、还有一种需求。结束时间为合同到期当天。

    timeTransformation(time,num) {
        // console.log(time)
        let date= new Date(time)
        // console.log(num)
        console.log(date)
		let day = date.getDate();
		let month = date.getMonth();
		let year = date.getFullYear();
        // console.log(day)
        // console.log(month+1)
        // console.log(year)
        
		//如果需要精确到时分秒
		// dateArr = this.dateFormmat(date,'yyyy-MM-dd hh:mm:ss').split(' ');
        
		year = year + parseInt((Number(month) + Number(num)) / 12);
		month = (Number(month) + Number(num)) % 12;

		//0-11 转变为 1-12
		month += 1;

		// 大月31天,小月30天,2月份只有28天(平年)或29天(闰年)
		// 每年一﹑三﹑五﹑七﹑八﹑十﹑十二这七个月为大月,均三十一天
		switch(month){
			case 1 :
			case 3 :
			case 5 :
			case 7 :
			case 8 :
			case 10 :
			case 12 :
				day > 31 ? day = 31 : '';
				break;
			case 4 :
			case 6 :
			case 9 :
			case 11 :
				day > 30 ? day = 30 : '';
				break;
			case 2 :
				this.isLeapYear(year) ? (day > 29 ? day = 29 : '') : (day > 28 ? day = 28 : ''); 
				break;
			default : 
				break;	
		}
		month < 10 ? (month = '0' + month) : '';
		day < 10 ? (day = '0' + day) : '';
        // let a=year + '-' + month + '-' + day + ' ' + dateArr[1];
        let a=year + '-' + month + '-' + day ;
        console.log(a);

		// return year + '-' + month + '-' + day + ' ' + dateArr[1];
		return year + '-' + month + '-' + day;
	},
    dateFormmat(date, format){
        console.log(date)
        console.log(format)
		if(null==date){
			return ''
		}
		if(typeof(date)=='string' || typeof date === 'number'){
			date = (typeof date === 'number') ? new Date(date) : new Date((date || '').replace(/-/g, '/'))
		}

		var o = { 
			"M+" : date.getMonth()+1, //month 
			"d+" : date.getDate(), //day 
			"h+" : date.getHours(), //hour 
			"m+" : date.getMinutes(), //minute 
			"s+" : date.getSeconds(), //second 
			"q+" : Math.floor((date.getMonth()+3)/3), //quarter 
			"S" : date.getMilliseconds() //millisecond 
		} 

		if(/(y+)/.test(format)) { 
			format = format.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length)); 
		} 

		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)); 
			} 
		} 
        console.log(format)
		return format; 
	},
    isLeapYear(year) {
		// 普通闰年:公历年份是4的倍数的,且不是100的倍数,为普通闰年。(如2004年就是闰年)
		// 世纪闰年:公历年份是整百数的,必须是400的倍数才是世纪闰年(如1900年不是世纪闰年,2000年是世纪闰年)
		return ((year % 4 == 0) && (year % 100 != 0)) ? true : ((year % 400) == 0) ? true : false;
	},

第二种写法,参考链接: 参考


版权声明:本文为pipizhou16原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。