1. 程式人生 > >js 從開始和結束時間得到中間所有天

js 從開始和結束時間得到中間所有天

    今天在論壇中看到一個帖子,給定輸入的字元型日期和結束的字元型日期,計算中間間隔的每一天的日期。正好專案不忙,就動手寫了一下,記錄下來吧。

    原問題

var start_time = "2015-2-1"
var end_time = "2015-3-1"

需求得到開始和結束時間之間所有天 return [ '2015-2-1',"2015-2-2" ... "2015-2-28","2015-3-1"]

method 1

<script>
// 獲取間隔天數
function getDays(day1, day2) {
	// 獲取入參字串形式日期的Date型日期
	var d1 = day1.getDate();
	var d2 = day2.getDate();

	// 定義一天的毫秒數
	var dayMilliSeconds  = 1000*60*60*24;
	
	// 獲取輸入日期的毫秒數
	var d1Ms = d1.getTime();
	var d2Ms = d2.getTime();
	
	// 定義返回值
	var ret;
	
	// 對日期毫秒數進行迴圈比較,直到d1Ms 大於等於 d2Ms 時退出迴圈
	// 每次迴圈結束,給d1Ms 增加一天
	for (d1Ms; d1Ms <= d2Ms; d1Ms += dayMilliSeconds) {
	
		// 如果ret為空,則無需新增","作為分隔符
		if (!ret) {
			// 將給的毫秒數轉換為Date日期
			var day = new Date(d1Ms);
			
			// 獲取其年月日形式的字串
			ret = day.getYMD();
		} else {
		
		// 否則,給ret的每個字元日期間新增","作為分隔符
			var day = new Date(d1Ms);
			ret = ret + ',' + day.getYMD();
		}
	}

	alert(ret); // 或可換為return ret;
}

// 給Date物件新增getYMD方法,獲取字串形式的年月日
Date.prototype.getYMD = function(){
    var retDate = this.getFullYear() + "-";  // 獲取年份。
    retDate += this.getMonth() + 1 + "-";    // 獲取月份。          
    retDate += this.getDate();               // 獲取日。
    return retDate;                          // 返回日期。
}

// 給String物件新增getDate方法,使字串形式的日期返回為Date型的日期
String.prototype.getDate = function(){
	var strArr = this.split('-');
	var date = new Date(strArr[0], strArr[1] - 1, strArr[2]);
	return date;
}

getDays('2015-2-1', '2015-3-1'); 
</script>

    上面的方法中,利用日期毫秒數比較的方式,同時讓開始的日期進行自增,避免了計算每個月有多少天的情況。

    getYMD 和 getDate 是分別在Date 和 String 原型上增加的方法,方便我們的使用。

method 2

開啟chrome瀏覽器的console控制檯


           可以看到3月32日和4月1日的getTime 是相等的,所以,可以利用這點,讓天數自增,來完成比較。

<script>
// 獲取間隔天數
function getDays(day1, day2) {
	// 獲取入參字串形式日期的Date型日期
	var st = day1.getDate();
	var et = day2.getDate();
	
	// 定義返回的陣列
	var retArr = [];

	// 迴圈,啟動日期不等於結束日期時,進行迴圈
	while (st.getTime() != et.getTime()) {
		
		// 將啟動日期的字串形式的日期存放進陣列
		retArr.push(st.getYMD());
		
		// 取得開始日期的天
		var tempDate = st.getDate();
		
		// 將開始日期st指向構造出的新的日期
		// 新的日期較之前的日期多加一天
		st = new Date(st.getFullYear(), st.getMonth(), st.getDate() + 1);
	}

	// 將結束日期的天放進陣列
	retArr.push(et.getYMD());
	
	alert(retArr); // 或可換為return ret;
}

// 給Date物件新增getYMD方法,獲取字串形式的年月日
Date.prototype.getYMD = function(){
   var retDate = this.getFullYear() + "-";  // 獲取年份。
   retDate += this.getMonth() + 1 + "-";    // 獲取月份。          
   retDate += this.getDate();               // 獲取日。
   return retDate;                          // 返回日期。
}

// 給String物件新增getDate方法,使字串形式的日期返回為Date型的日期
String.prototype.getDate = function(){
	var strArr = this.split('-');
	var date = new Date(strArr[0], strArr[1] - 1, strArr[2]);
	return date;
}

getDays('2015-2-9', '2015-3-8'); 
</script>

    這裡由於while迴圈的條件是 st.getTime() != et.getTime() 所以,while迴圈內,結束日期的字元型日期不會放進結果陣列,所以要在while結束後將結束日期放進結果陣列中。

method 3

<script>
// 獲取間隔天數
function getDays(day1, day2) {
	// 獲取入參字串形式日期的Date型日期
	var st = day1.getDate();
	var et = day2.getDate();
	
	var retArr = [];
	
	// 獲取開始日期的年,月,日
	var yyyy = st.getFullYear(),
		mm = st.getMonth(),
		dd = st.getDate();
	
	// 迴圈
	while (st.getTime() != et.getTime()) {
		retArr.push(st.getYMD());
		
		// 使用dd++進行天數的自增
		st = new Date(yyyy, mm, dd++);
	}

	// 將結束日期的天放進陣列
	retArr.push(et.getYMD());
	
	alert(retArr); // 或可換為return ret;
}

// 給Date物件新增getYMD方法,獲取字串形式的年月日
Date.prototype.getYMD = function(){

    // 將結果放在陣列中,使用陣列的join方法返回連線起來的字串,並給不足兩位的天和月十位上補零
    return [this.getFullYear(), fz(this.getMonth() + 1), fz(this.getDate())].join("-");
}

// 給String物件新增getDate方法,使字串形式的日期返回為Date型的日期
String.prototype.getDate = function(){
	var strArr = this.split('-');
	return new Date(strArr[0], strArr[1] - 1, strArr[2]);
}

// 給月和天,不足兩位的前面補0
function fz(num) {
	if (num < 10) {
		num = "0" + num;
	}
	return num
}

getDays('2015-2-9', '2015-3-8'); 
</script>

方法3 中做了下面兩點改進

  • 將while迴圈內的new Date() 時的入參定義到了外面,不用每次都使用st.getFullYear(),st.getMonth(),st.getDate() 的去獲取,且new Date() 的天可以直接使用dd++,提高了運算效率
  • getYMD 中,直接使用[this.getFullYear(), fz(this.getMonth() + 1), fz(this.getDate())].join("-") 替代了之前的四行程式碼,且給月份和天進行了補位,在不足兩位的時候前面補0,這樣處理過的8位的字元日期可以儲存資料庫,再拿出來時也方便處理。