2012-05-23 97 views
19

可能重複:
PHP DateTime::modify adding and subtracting months如何增加1個月的日期沒有跳過即二月

我有一個起始日期(即2011-01-30),並要添加1個月。

問題在於定義一個月的情況。所以,如果我使用下面的代碼:

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57'); 
$d1->add(new DateInterval('P1M')); 
echo $d1->format('Y-m-d H:i:s'); 

我得到以下結果:2011-03-02 15點57分57秒

的問題是,我需要它使用下列規則:

  • 如果我添加1個月,將剛上月部分加1,保留日部分 (2011-01-15會變成2011-02-15)
  • 如果當天沒有在現有的一個月我們會結束,我們把它的最後一天 (2011-01-30將成爲2011-02-28)

在php中是否有一個常見的功能可以做到這一點,或者我必須自己編寫它? 也許我只是缺少一個參數或什麼!?

+4

如果你迭代了多個月,你需要小心你不會在28日被「卡住」。例如,如果你開始於1/30 .. 2/28 .. 3/28,那麼你可能想要3/30。 – Matthew

+3

我最近處理這個實現商業計費系統。沒有預先解決的解決方案。您必須跟蹤您的開始日期,遞增月份,查看下一個月是否存在該日期,如果沒有,請使用該月份的最後一天。實際上它並不複雜,但它會覺得你不應該編寫那麼多的代碼。 – Endophage

+0

這裏的要求是添加*日曆月*。跳到本月的第一天,添加你想要的月份,然後跳回到你開始的日期編號*或*如果月份短於開始日期編號,則新月份的最後一天。 – Jason

回答

11

看來,有沒有爲它準備的功能,所以我自己寫的。 這應該解決我的問題。無論如何,感謝你的回答和評論。 如果您會發現一些錯誤,請在評論中提供。

此函數計算在添加某個月後我將結束的月份和年份。然後它檢查日期是否正確。如果不是,我們有這樣的情況,那一天不在目標月份,所以我們改爲在這個月的最後一天。 使用PHP 5.3.10進行測試。

<?php 
$monthToAdd = 1; 

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57'); 

$year = $d1->format('Y'); 
$month = $d1->format('n'); 
$day = $d1->format('d'); 

$year += floor($monthToAdd/12); 
$monthToAdd = $monthToAdd%12; 
$month += $monthToAdd; 
if($month > 12) { 
    $year ++; 
    $month = $month % 12; 
    if($month === 0) 
     $month = 12; 
} 

if(!checkdate($month, $day, $year)) { 
    $d2 = DateTime::createFromFormat('Y-n-j', $year.'-'.$month.'-1'); 
    $d2->modify('last day of'); 
}else { 
    $d2 = DateTime::createFromFormat('Y-n-d', $year.'-'.$month.'-'.$day); 
} 
$d2->setTime($d1->format('H'), $d1->format('i'), $d1->format('s')); 
echo $d2->format('Y-m-d H:i:s'); 
+1

完美。我需要這個,但對於互斥時間段 - 我只是在'$ day = $ d1-> format('d');' – Simeon

+0

'之後添加了'$ day = $ day-1;''負值的一些問題:替換$ year + = floor($ monthToAdd/12);'by'$ year + = $ monthToAdd> = 0? ($ monthToAdd/12):ceil($ monthToAdd/12);'和if(!checkdate())'之前,添加以下內容:'if($ month <0){month_details = 12 + $ month% 12; $ year--; }'。用PHP 5.6.29測試。希望它能幫助別人。 – sk001

11

除DateInterval外,您還有其他幾種選擇。

下面是使用strtotime()例子:

http://www.brightcherry.co.uk/scribbles/php-adding-and-subtracting-dates/

// Subtracting days from a date 
$date = "1998-08-14"; 
$newdate = strtotime ('-3 day' , strtotime ($date)) ; 
$newdate = date ('Y-m-j' , $newdate); 

echo $newdate; 

...

// Subtracting months from a date 
$date = "1998-08-14"; 
$newdate = strtotime ('-3 month' , strtotime ($date)) ; 
$newdate = date ('Y-m-j' , $newdate); 

echo $newdate; 

這裏的一些鏈接,DateInterval

問:究竟怎麼做定義一個 「月」?

默認值#1):一個 「月」 是一個 「月」 - 不管#/天

默認值#2):一個 「月」 是(例如)

30天DEF 3#):一個「月」是 隨後的幾個月

的第一個星期一的#/天等等等等

問:究竟什麼是你的「定義」?

+1

這裏也一樣。如果我嘗試:$ date =「2011-01-30」; $ newdate = strtotime('+1 month',strtotime($ date)); echo date('Y-m-d',$ newdate);我得到2011-03-02,而不是2011-02-28,因爲我需要 – Kasihasi

+0

正如你可以看到我的問題,我用你的Def#1。 – Kasihasi

+2

如果你使用strtotime(),那麼避免跳過二月份的最好方法是添加$ date = strtotime('+1 month的第一天'); –

0

好的 - 據我所知,你還沒有清楚地定義「月」的含義。

但這裏有一個更多的功能,可以幫助:

http://php.net/manual/en/function.getdate.php

/* Function to find the first and last day of the month from the given date. 
* 
* Author Binu v Pillai   [email protected] 
* @Param   String    yyyy-mm-dd 
* 
*/ 
function findFirstAndLastDay($anyDate) 
{ 
    //$anyDate   = '2009-08-25'; // date format should be yyyy-mm-dd 
    list($yr,$mn,$dt) = split('-',$anyDate); // separate year, month and date 
    $timeStamp   = mktime(0,0,0,$mn,1,$yr); //Create time stamp of the first day from the give date. 
    $firstDay   =  date('D',$timeStamp); //get first day of the given month 
    list($y,$m,$t)  =  split('-',date('Y-m-t',$timeStamp)); //Find the last date of the month and separating it 
    $lastDayTimeStamp = mktime(0,0,0,$m,$t,$y);//create time stamp of the last date of the give month 
    $lastDay   = date('D',$lastDayTimeStamp);// Find last day of the month 
    $arrDay    = array("$firstDay","$lastDay"); // return the result in an array format. 

    return $arrDay; 
} 
相關問題