increment date by one month

假设我有一个以下格式的日期: 2010-12-11(年-月-日)

使用 PHP,我希望将日期增加一个月,如果有必要,我希望年份自动增加(即从2012年12月增加到2013年1月)。

Regards.

295788 次浏览

使用 DateTime::add

$start = new DateTime("2010-12-11", new DateTimeZone("UTC"));
$month_later = clone $start;
$month_later->add(new DateInterval("P1M"));

我使用 克隆人是因为 add 修改了原始对象,这可能并不需要。

strtotime( "+1 month", strtotime( $time ) );

这将返回一个可以与 date 函数一起使用的时间戳

$time = strtotime("2010.12.11");
$final = date("Y-m-d", strtotime("+1 month", $time));


// Finally you will have the date you're looking for.

我需要类似的功能,除了一个月周期(加上月份,减去1天)。在搜索了 S.O. 一段时间后,我得以制作出这个即插即用的解决方案:

function add_months($months, DateTime $dateObject)
{
$next = new DateTime($dateObject->format('Y-m-d'));
$next->modify('last day of +'.$months.' month');


if($dateObject->format('d') > $next->format('d')) {
return $dateObject->diff($next);
} else {
return new DateInterval('P'.$months.'M');
}
}


function endCycle($d1, $months)
{
$date = new DateTime($d1);


// call second function to add the months
$newDate = $date->add(add_months($months, $date));


// goes back 1 day from date, remove if you want same day of month
$newDate->sub(new DateInterval('P1D'));


//formats final date to Y-m-d form
$dateReturned = $newDate->format('Y-m-d');


return $dateReturned;
}

例如:

$startDate = '2014-06-03'; // select date in Y-m-d format
$nMonths = 1; // choose how many months you want to move ahead
$final = endCycle($startDate, $nMonths); // output: 2014-07-02
(date('d') > 28) ? date("mdY", strtotime("last day of next month")) : date("mdY", strtotime("+1 month"));

这将补偿2月份和其他31天的月份。当然,您可以做更多的检查,以获得更精确的“下个月的这一天”相对日期格式(它不能正常工作,详见下文) ,您也可以使用 DateTime。

DateInterval('P1M')strtotime("+1 month")基本上都是盲目地增加31天,而不管接下来一个月的天数是多少。

  • 2010-01-31 => March 3rd
  • 2012-01-31 = > 3月2日(闰年)

I use this way:-

 $occDate='2014-01-28';
$forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=02




/*****************more example****************/
$occDate='2014-12-28';


$forOdNextMonth= date('m', strtotime("+1 month", strtotime($occDate)));
//Output:- $forOdNextMonth=01


//***********************wrong way**********************************//
$forOdNextMonth= date('m', strtotime("+1 month", $occDate));
//Output:- $forOdNextMonth=02; //instead of $forOdNextMonth=01;
//******************************************************************//

Thanks Jason, your post was very helpful. I reformatted it and added more comments to help me understand it all. In case that helps anyone, I have posted it here:

function cycle_end_date($cycle_start_date, $months) {
$cycle_start_date_object = new DateTime($cycle_start_date);


//Find the date interval that we will need to add to the start date
$date_interval = find_date_interval($months, $cycle_start_date_object);


//Add this date interval to the current date (the DateTime class handles remaining complexity like year-ends)
$cycle_end_date_object = $cycle_start_date_object->add($date_interval);


//Subtract (sub) 1 day from date
$cycle_end_date_object->sub(new DateInterval('P1D'));


//Format final date to Y-m-d
$cycle_end_date = $cycle_end_date_object->format('Y-m-d');


return $cycle_end_date;
}


//Find the date interval we need to add to start date to get end date
function find_date_interval($n_months, DateTime $cycle_start_date_object) {
//Create new datetime object identical to inputted one
$date_of_last_day_next_month = new DateTime($cycle_start_date_object->format('Y-m-d'));


//And modify it so it is the date of the last day of the next month
$date_of_last_day_next_month->modify('last day of +'.$n_months.' month');


//If the day of inputted date (e.g. 31) is greater than last day of next month (e.g. 28)
if($cycle_start_date_object->format('d') > $date_of_last_day_next_month->format('d')) {
//Return a DateInterval object equal to the number of days difference
return $cycle_start_date_object->diff($date_of_last_day_next_month);
//Otherwise the date is easy and we can just add a month to it
} else {
//Return a DateInterval object equal to a period (P) of 1 month (M)
return new DateInterval('P'.$n_months.'M');
}
}


$cycle_start_date = '2014-01-31'; // select date in Y-m-d format
$n_months = 1; // choose how many months you want to move ahead
$cycle_end_date = cycle_end_date($cycle_start_date, $n_months); // output: 2014-07-02

请首先将您的日期格式设置为12-12-2012

使用这个函数后,它的工作正常;

$date =  date('d-m-Y',strtotime("12-12-2012 +2 Months");

这里12-12-2012是你的日期,+ 2个月是该月的增量;

你还增加了年份,日期

strtotime("12-12-2012 +1 Year");

Ans 是12-12-2013

function dayOfWeek($date){
return DateTime::createFromFormat('Y-m-d', $date)->format('N');
}

用法例子:

echo dayOfWeek(2016-12-22);
// "4"
echo dayOfWeek(date('Y-m-d'));
// "4"
$date = strtotime("2017-12-11");
$newDate = date("Y-m-d", strtotime("+1 month", $date));

如果你想增加天,你也可以这样做

$date = strtotime("2017-12-11");
$newDate = date("Y-m-d", strtotime("+5 day", $date));

对于任何人寻找一个答案,任何日期格式。

echo date_create_from_format('d/m/Y', '15/04/2017')->add(new DateInterval('P1M'))->format('d/m/Y');

只要改变日期格式。

You can use DateTime::modify like this :

$date = new DateTime('2010-12-11');
$date->modify('+1 month');

请参阅文档:

Https://php.net/manual/en/datetime.modify.php

Https://php.net/manual/en/class.datetime.php


2021年1月最新情况: 评论提出的正确错误

这个解决方案有一些问题,月与31天,如五月等。

例如: 从5月31日跳到7月1日,这是不正确的。

要纠正这个问题,可以创建这个自定义函数

function addMonths($date,$months){
    

$init=clone $date;
$modifier=$months.' months';
$back_modifier =-$months.' months';
   

$date->modify($modifier);
$back_to_init= clone $date;
$back_to_init->modify($back_modifier);
   

while($init->format('m')!=$back_to_init->format('m')){
$date->modify('-1 day')    ;
$back_to_init= clone $date;
$back_to_init->modify($back_modifier);
}
}

然后你可以这样使用它:

$date = new DateTime('2010-05-31');
addMonths($date, 1);
print_r($date);
//DateTime Object ( [date] => 2010-06-30 00:00:00.000000 [timezone_type] => 3 [timezone] => Europe/Berlin )

这个解决方案是在 PHP.net 中找到的,由 jenspj: https://www.php.net/manual/fr/datetime.modify.php#107592发布

在输入框中输入一个日期,然后单击 jquery 中的 get day from date 按钮

$(document).ready( function() {
$("button").click(function(){
var day = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var a = new Date();
$(".result").text(day[a.getDay()]);


});
});
 <?php
$selectdata ="select fromd,tod  from register where username='$username'";
$q=mysqli_query($conm,$selectdata);
$row=mysqli_fetch_array($q);


$startdate=$row['fromd'];
$stdate=date('Y', strtotime($startdate));


$endate=$row['tod'];
$enddate=date('Y', strtotime($endate));


$years = range ($stdate,$enddate);
echo '<select name="years" class="form-control">';
echo '<option>SELECT</option>';
foreach($years as $year)
{   echo '<option value="'.$year.'"> '.$year.' </option>';  }
echo '</select>'; ?>

所有提出的解决方案
Strtotime ()和 DateTime::addDateTime::modify给出有时无效的结果。
例子:
-31.08.2019 + 1个月等于01.10.2019而不是30.09.2019
- 29.02.2020 + 1 year 给出01.03.2021而不是28.02.2021
(在 PHP 5.5,PHP 7.3上测试)

下面是我基于 安吉洛提出的想法的函数,它解决了这个问题:

// $time - unix time or date in any format accepted by strtotime() e.g. 2020-02-29
// $days, $months, $years - values to add
// returns new date in format 2021-02-28
function addTime($time, $days, $months, $years)
{
// Convert unix time to date format
if (is_numeric($time))
$time = date('Y-m-d', $time);


try
{
$date_time = new DateTime($time);
}
catch (Exception $e)
{
echo $e->getMessage();
exit;
}


if ($days)
$date_time->add(new DateInterval('P'.$days.'D'));


// Preserve day number
if ($months or $years)
$old_day = $date_time->format('d');


if ($months)
$date_time->add(new DateInterval('P'.$months.'M'));


if ($years)
$date_time->add(new DateInterval('P'.$years.'Y'));


// Patch for adding months or years
if ($months or $years)
{
$new_day = $date_time->format("d");


// The day is changed - set the last day of the previous month
if ($old_day != $new_day)
$date_time->sub(new DateInterval('P'.$new_day.'D'));
}
// You can chage returned format here
return $date_time->format('Y-m-d');
}

用法例子:

echo addTime('2020-02-29', 0, 0, 1); // add 1 year (result: 2021-02-28)
echo addTime('2019-08-31', 0, 1, 0); // add 1 month (result: 2019-09-30)
echo addTime('2019-03-15', 12, 2, 1); // add 12 days, 2 months, 1 year (result: 2019-09-30)

只是更新答案的简单方法,找到日期后没有的月份。由于标出的最佳答案不能给出正确的答案。

<?php


$date = date('2020-05-31');
$current = date("m",strtotime($date));
$next = date("m",strtotime($date."+1 month"));
if($current==$next-1){
$needed = date('Y-m-d',strtotime($date." +1 month"));
}else{
$needed = date('Y-m-d', strtotime("last day of next month",strtotime($date)));
}
echo "Date after 1 month from 2020-05-31 would be : $needed";


?>

如果你想得到一个月后的日期,你可以这样做

echo date('Y-m-d', strtotime('1 month'));

如果你想得到两个月后的日期,你可以通过这样做来实现

echo date('Y-m-d', strtotime('2 month'));

等等,就这样。

//ECHO MONTHS BETWEEN TWO TIMESTAMPS
$my_earliest_timestamp = 1532095200;
$my_latest_timestamp = 1554991200;


echo '<pre>';
echo "Earliest timestamp: ". date('c',$my_earliest_timestamp) ."\r\n";
echo "Latest timestamp: " .date('c',$my_latest_timestamp) ."\r\n\r\n";


echo "Month start of earliest timestamp: ". date('c',strtotime('first day of '. date('F Y',$my_earliest_timestamp))) ."\r\n";
echo "Month start of latest timestamp: " .date('c',strtotime('first day of '. date('F Y',$my_latest_timestamp))) ."\r\n\r\n";


echo "Month end of earliest timestamp: ". date('c',strtotime('last day of '. date('F Y',$my_earliest_timestamp)) + 86399) ."\r\n";
echo "Month end of latest timestamp: " .date('c',strtotime('last day of '. date('F Y',$my_latest_timestamp)) + 86399) ."\r\n\r\n";


$sMonth = strtotime('first day of '. date('F Y',$my_earliest_timestamp));
$eMonth = strtotime('last day of '. date('F Y',$my_earliest_timestamp)) + 86399;
$xMonth = strtotime('+1 month', strtotime('first day of '. date('F Y',$my_latest_timestamp)));


while ($eMonth < $xMonth) {
echo "Things from ". date('Y-m-d',$sMonth) ." to ". date('Y-m-d',$eMonth) ."\r\n\r\n";
$sMonth = $eMonth + 1; //add 1 second to bring forward last date into first second of next month.
$eMonth = strtotime('last day of '. date('F Y',$sMonth)) + 86399;
}

我发现 mtkime ()函数对此非常有效:

$start_date="2021-10-01";
$start_date_plus_a_month=date("Y-m-d", mktime(0, 0, 0, date("m",strtotime($start_date))+1, date("d",strtotime($start_date)), date("Y",strtotime($start_date))));

结果: 2021-11-01

I like to subtract 1 from the 'day' to produce '2021-10-31' which can be useful if you want to display a range across 12 months, e.g. Oct 1, 2021 to Sep 30 2022

$start_date_plus_a_year=date("Y-m-d", mktime(0, 0, 0, date("m",strtotime($start_date))+12, date("d",strtotime($start_date))-1, date("Y",strtotime($start_date))));

结果: 2022-09-30

它可以处理所有日期,例如2013-05-31将显示6月30日。

$date = "2013-05-31";
$date = date('Y-m-d', strtotime( "last day of next month", strtotime( $date ) ) );
echo $date;