484

How can I get the last day of the month in PHP?

Given:

$a_date = "2009-11-23"

I want 2009-11-30; and given

$a_date = "2009-12-23"

I want 2009-12-31.

Foreever
  • 7,099
  • 8
  • 53
  • 55
Mithun Sreedharan
  • 49,883
  • 70
  • 181
  • 236

30 Answers30

996

t returns the number of days in the month of a given date (see the docs for date):

$a_date = "2009-11-23";
echo date("Y-m-t", strtotime($a_date));
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
  • 82
    @Mugunth If you are working with dates 24 years in the future you may run into problems sooner than 2038, however, servers are already moving over to 64-bit architecture which will give us about 292 billion years to correct the problem. – None Feb 07 '13 at 05:59
  • 2
    in procedural -> $date1 = $year.'-'.$month; $d = date_create_from_format('Y-m',$date1); $last_day = date_format($d, 't'); – kayla Jul 16 '13 at 01:05
  • 27
    With `DateTime` you can do something like this: `(new DateTime('2009-11-23'))->modify('last day of')` – Victor Feb 24 '16 at 16:31
  • If you're using Carbon PHP you can use daysInMonth getter – astroanu Mar 01 '16 at 05:08
  • it is not working if we put `echo date("Y-m-t", strtotime(date('2019-02-29')));`, it should be output `28`. but showing `03-31` – Himanshu Mar 09 '19 at 10:48
  • @Mugunth I am working on a project on RPi3 while dates are beyond 2040 and everything working perfectly. – webcoder May 29 '19 at 10:48
  • @J.Money good software is software which can run on the same machine regardless of what date it is. – barell Nov 14 '19 at 12:33
  • 2
    @victor you should bump your comment as answer for the sole reason that it results in readable and understandable code. Clearly using Y-m-t would work as well but who without looking at the docs would know what "t" is? – theking2 Aug 21 '21 at 08:33
  • 1
    @Himanshu why are you passing on a non-existent date? – Alex78191 Oct 18 '21 at 07:28
156

If you're using a 32-bit system, then the strtotime() code will fail after the year 2038 due to the Year 2038 problem.

For example, on a 32-bit system, this code will echo 1970-01-31:

$a_date = "2040-11-23";
echo date("Y-m-t", strtotime($a_date));

If you need your code to support 32-bit systems, then you should instead use the DateTime function:

$d = new DateTime('2040-11-23'); 
echo $d->format('Y-m-t');

That code will correctly output 2040-11-30 on both a 32-bit or 64-bit system.

Pikamander2
  • 7,332
  • 3
  • 48
  • 69
Mugunth
  • 2,368
  • 1
  • 21
  • 28
  • 27
    I will be 71 and retired by then, so not a problem for me! j/k But seriously folks -- heed this warning! – Volomike Nov 02 '12 at 03:44
  • 19
    This assumes you are running a 32-bit version of PHP. – None Feb 07 '13 at 06:00
  • 1
    why is this alarming fact about strtotime not mentioned in the php docu http://php.net/manual/de/function.strtotime.php ? – Adam Dec 19 '15 at 15:08
  • 2
    @Adam It is now, not sure if it was when you checked. http://php.net/manual/de/function.strtotime.php#refsect1-function.strtotime-notes – Mave Mar 22 '16 at 12:06
  • 4
    As of 2018, the `strtotime` code gives me this result: **2040-11-30** – Eje Aug 29 '18 at 18:34
  • 1
    Please note that the format function will return a string value, not a DateTime object. If you need the formatted date to be a DateTime object you must create a new instance of DateTime and pass it the string returned from the format function: $d = new DateTime( '2040-11-23' ); $dateString = $d->format( 'Y-m-t' ); $formattedDateTime = new DateTime( $dateString ); – MarkusMulholland Feb 11 '20 at 12:51
149

I know this is a little bit late but i think there is a more elegant way of doing this with PHP 5.3+ by using the DateTime class :

$date = new DateTime('now');
$date->modify('last day of this month');
echo $date->format('Y-m-d');
Hannoun Yassir
  • 20,583
  • 23
  • 77
  • 112
  • 30
    In one line: $date = new DateTime('last day of this month'); – Harold Nov 27 '14 at 15:27
  • 7
    You might want to add $date->modify('last day of this month')->setTime(23,59,59); if you would like to use this dateTime for comparison where time matters. (This gives you the last second of the month) – omgitsdrobinoha Nov 20 '16 at 12:57
  • 12
    This works: `$date = new DateTime('last day of 2020-2');` –  Feb 20 '17 at 16:48
  • **NO!!** This only works for the *current month* and *not a specified month as requested by the OP*. Please update your post and I'll remove my down-vote which I'm using as a bookmark to avoid using this code as-is if I need to determine this again in the future and come across this page. – John Sep 14 '17 at 09:07
  • 5
    @John you are wrong. the last day is calculated using the $date object and not the system date. Try it by changing the first line with this : `$date = DateTime::createFromFormat('m/d/Y', '1/10/2014');` – Hannoun Yassir Sep 14 '17 at 09:50
  • *Look at your post*: **last day of this month**. – John Sep 14 '17 at 10:02
  • 7
    If you were to think or at least try what I asked you to do you would see that _this month_ means the value of the month in the DateTime object not the system's date. If you can't type/run php code this might help : http://sandbox.onlinephpfunctions.com/code/290b69fffcf3bc12d684479254c714ee6089b092 – Hannoun Yassir Sep 14 '17 at 12:43
  • @HannounYassir, this answer is elegant and I have tested it all the way to 2050 including leap years calculations for Feb last day of month, and the results are correct. I am a beginner on PHP, and this has helped tremendously. There is some good magic happening on the background and was wondering, if you could point me to the feature where the modify function recognizes the string 'last day of this month'. – CesarB Jun 03 '20 at 15:57
  • 3
    @CesarB It is something called "Relative Formats". You can read more about it here : https://www.php.net/manual/en/datetime.formats.relative.php – Hannoun Yassir Jun 03 '20 at 16:15
  • Other option with time: $date->modify('first day of next month midnight'); changes "2038-05-25 14:44:44" to "2038-06-01 00:00:00" for example. – Den Jul 15 '21 at 10:02
  • @John just change the `now` to date anything you want – syahid246 Oct 08 '22 at 05:52
95

There is also the built in PHP function cal_days_in_month()?

"This function will return the number of days in the month of year for the specified calendar." http://php.net/manual/en/function.cal-days-in-month.

echo cal_days_in_month(CAL_GREGORIAN, 11, 2009); 
// = 30
MPV
  • 1,644
  • 14
  • 15
  • 5
    This answer is much simpler and appropriate than the use of strtoTime. I don't see any downsides. To the top you go. – TZubiri Nov 17 '16 at 20:51
29

This should work:

$week_start = strtotime('last Sunday', time());
$week_end = strtotime('next Sunday', time());

$month_start = strtotime('first day of this month', time());
$month_end = strtotime('last day of this month', time());

$year_start = strtotime('first day of January', time());
$year_end = strtotime('last day of December', time());

echo date('D, M jS Y', $week_start).'<br/>';
echo date('D, M jS Y', $week_end).'<br/>';

echo date('D, M jS Y', $month_start).'<br/>';
echo date('D, M jS Y', $month_end).'<br/>';

echo date('D, M jS Y', $year_start).'<br/>';
echo date('D, M jS Y', $year_end).'<br/>';
kaleazy
  • 5,922
  • 2
  • 47
  • 51
27

The most elegant for me is using DateTime

I wonder I do not see DateTime::createFromFormat, one-liner

$lastDay = \DateTime::createFromFormat("Y-m-d", "2009-11-23")->format("Y-m-t");
john Smith
  • 17,409
  • 11
  • 76
  • 117
20

Try this , if you are using PHP 5.3+,

$a_date = "2009-11-23";
$date = new DateTime($a_date);
$date->modify('last day of this month');
echo $date->format('Y-m-d');

For finding next month last date, modify as follows,

 $date->modify('last day of 1 month');
 echo $date->format('Y-m-d');

and so on..

Mohammed Safeer
  • 20,751
  • 8
  • 75
  • 78
  • This is the correct answer. Just to complement your answer, you can also use it like this `$date = new DateTime('last day of 2022-06');`. – jawira Jun 10 '22 at 08:16
17

You could create a date for the first of the next month, and then use strtotime("-1 day", $firstOfNextMonth)

nikc.org
  • 16,462
  • 6
  • 50
  • 83
  • an alternative method using the same approach is to give mktime the 0th day of the next month `mktime(0, 0, 0, $month+1, 0, $year);` – George Nov 21 '13 at 08:59
  • As to me, usage of `strtotime()` and `mktime()` is discouraged bec. of known bugs like date determination on the edge of the months and leap year calaculations. Since `DateTime` is available, you should use this class to avoid any problems in future. Like said many times before me, both these function `strtotime()` and `mktime()` will fail after 2038. That's why I downvoted ... – Paul T. Rawkeen Dec 04 '13 at 12:33
  • @PaulT.Rawkeen This answer is more than 4 years old. As with anything on the internet, age should be a factor when gauging relevance and usefulness. Further more, IMHO, the halving time for anything related to technology is particularly short. – nikc.org Dec 12 '13 at 11:40
  • @nikc.org I agree, especially regarding time of life for all technical solutions and ways of solving problems. In this particular case, answer has relatively good number of upvotes and probably, someone (_junior programmer_) will consider this answer as acceptable solution bec. it is short and elegant :) and he will probably get the expected result, but as time goes by, this way of solving such kind of problems becomes tricky and we _should_ warn about such facts when its possible. _Kind regards_. – Paul T. Rawkeen Dec 12 '13 at 12:28
15

You can find last day of the month several ways. But simply you can do this using PHP strtotime() and date() function.I'd imagine your final code would look something like this:

$a_date = "2009-11-23";
echo date('Y-m-t',strtotime($a_date));

Live Demo

But If you are using PHP >= 5.2 I strongly suggest you use the new DateTime object. For example like below:

$a_date = "2009-11-23";
$date = new DateTime($a_date);
$date->modify('last day of this month');
echo $date->format('Y-m-d');

Live Demo

Also, you can solve this using your own function like below:

/**
 * Last date of a month of a year
 *
 * @param[in] $date - Integer. Default = Current Month
 *
 * @return Last date of the month and year in yyyy-mm-dd format
 */
function last_day_of_the_month($date = '')
{
    $month  = date('m', strtotime($date));
    $year   = date('Y', strtotime($date));
    $result = strtotime("{$year}-{$month}-01");
    $result = strtotime('-1 second', strtotime('+1 month', $result));

    return date('Y-m-d', $result);
}

$a_date = "2009-11-23";
echo last_day_of_the_month($a_date);
Faisal
  • 4,591
  • 3
  • 40
  • 49
11

Your solution is here..

$lastday = date('t',strtotime('today'));
bensiu
  • 24,660
  • 56
  • 77
  • 117
Vineet Kadkol
  • 321
  • 3
  • 5
8

Nowadays DateTime does this quite conveniently if you have month and year you can

$date = new DateTime('last day of '.$year.'-'.$month);

From another DateTime object that would be

$date = new DateTime('last day of '.$otherdate->format('Y-m'));
Max
  • 2,561
  • 1
  • 24
  • 29
7

If you use the Carbon API extension for PHP DateTime, you can get the last day of the month with:

$date = Carbon::now();
$date->addMonth();
$date->day = 0;
echo $date->toDateString(); // use toDateTimeString() to get date and time 
eaykin
  • 3,713
  • 1
  • 37
  • 33
  • Actually, if you set day to -1 it will get the last but one. So you must set day to 0 in order to get the last day. `$date->day = 0;` – Giovanne Afonso Oct 29 '14 at 02:48
  • thank you @GiovanneAfonso that is correct. I set the day to 0 and tested the answer. – eaykin Oct 29 '14 at 11:04
  • 1
    If you are using Carbon, a one-liner approach is to use: Carbon::Now()->endOfMonth(). However, endOfMonth() is a modifier, so use "clone" if you have an existing variable holding a Carbon date (or the date will be modified). – Charlie Dalsass Apr 12 '16 at 17:47
4

You can also use it with datetime

$date = new \DateTime();
$nbrDay = $date->format('t');
$lastDay = $date->format('Y-m-t');
Ajouve
  • 9,735
  • 26
  • 90
  • 137
4

Carbon API extension for PHP DateTime

Carbon::parse("2009-11-23")->lastOfMonth()->day;

or

Carbon::createFromDate(2009, 11, 23)->lastOfMonth()->day;

will return

30
Christian Lescuyer
  • 18,893
  • 5
  • 49
  • 45
josef
  • 872
  • 9
  • 8
3
$date1 = $year.'-'.$month; 
$d = date_create_from_format('Y-m',$date1); 
$last_day = date_format($d, 't');
kayla
  • 156
  • 1
  • 12
3

If you have a month wise get the last date of the month then,

public function getLastDateOfMonth($month)
    {
        $date = date('Y').'-'.$month.'-01';  //make date of month 
        return date('t', strtotime($date)); 
    }

$this->getLastDateOfMonth(01); //31
Kaushik shrimali
  • 1,178
  • 8
  • 15
3

2 lines code and you are done:

$oDate = new DateTime("2019-11-23");

// now your date object has been updated with last day of month    
$oDate->setDate($oDate->format("Y"),$oDate->format("m"),$oDate->format("t"));

// or to just echo you can skip the above line using this
echo $oDate->format("Y-m-t");
justnajm
  • 4,422
  • 6
  • 36
  • 56
2

Using Zend_Date it's pretty easy:

$date->setDay($date->get(Zend_Date::MONTH_DAYS));
mkerstner
  • 121
  • 4
2

An other way using mktime and not date('t') :

$dateStart= date("Y-m-d", mktime(0, 0, 0, 10, 1, 2016)); //2016-10-01
$dateEnd = date("Y-m-d", mktime(0, 0, 0, 11, 0, 2016)); //This will return the last day of october, 2016-10-31 :)

So this way it calculates either if it is 31,30 or 29

2

I am using strtotime with cal_days_in_month as following:

$date_at_last_of_month=date('Y-m-d', strtotime('2020-4-1
+'.(cal_days_in_month(CAL_GREGORIAN,4,2020)-1).' day'));
Rani
  • 432
  • 6
  • 9
1

Here is a complete function:

public function get_number_of_days_in_month($month, $year) {
    // Using first day of the month, it doesn't really matter
    $date = $year."-".$month."-1";
    return date("t", strtotime($date));
}

This would output following:

echo get_number_of_days_in_month(2,2014);

Output: 28

Firze
  • 3,939
  • 6
  • 48
  • 61
1

There are ways to get last day of month.

//to get last day of current month
echo date("t", strtotime('now'));

//to get last day from specific date
$date = "2014-07-24";
echo date("t", strtotime($date));

//to get last day from specific date by calendar
$date = "2014-07-24";
$dateArr=explode('-',$date);
echo cal_days_in_month(CAL_GREGORIAN, $dateArr[1], $dateArr[0]); 
vineet
  • 13,832
  • 10
  • 56
  • 76
1

I am late but there are a handful of easy ways to do this as mentioned:

$days = date("t");
$days = cal_days_in_month(CAL_GREGORIAN, date('m'), date('Y'));
$days = date("j",mktime (date("H"),date("i"),date("s"),(date("n")+1),0,date("Y")));

Using mktime() is my go to for complete control over all aspects of time... I.E.

echo "<br> ".date("Y-n-j",mktime (date("H"),date("i"),date("s"),(11+1),0,2009));

Setting the day to 0 and moving your month up 1 will give you the last day of the previous month. 0 and negative numbers have the similar affect in the different arguements. PHP: mktime - Manual

As a few have said strtotime isn't the most solid way to go and little if none are as easily versatile.

JSG
  • 390
  • 1
  • 4
  • 13
1

if you want to go back few months you can do something like this as well.

 $list = [
        0, 1, 2, 3
    ];

    $date = new \Datetime();
    $dates = [];
    foreach($list as $item)
    {

        $set = clone $date;
        $set->modify("-$item month ");
       $dates[] = $set->modify("last day of this month");
       
    }
    return $dates;
codediesel
  • 43
  • 6
0

I have wrapped it in my date time helper class here https://github.com/normandqq/Date-Time-Helper using $dateLastDay = Model_DTHpr::getLastDayOfTheMonth();

And it is done

Norman
  • 79
  • 3
0
    $startDate = '2011-12-01';
    $endDate = date('Y-m');
    while (true) {
        try {
            $startDateTime = new DateTime($startDate);
            $startDateTime->add(new DateInterval('P1M'));
            $startDate = $startDateTime->format('Y-m-d');
            $endTime = $startDateTime->format('Y-m-t');
            echo $startDate . ' => ' . $endTime . PHP_EOL;
            if ($startDateTime->format('Y-m') == $endDate) {
                break;
            }
        } catch (Exception $exception) {
            var_dump($exception->getMessage());
            break;
        }
    }

After testing many solutions, this works best for me.

Winn Minn Soe
  • 341
  • 1
  • 2
  • 4
-1

I needed the last day of the next month, maybe someone will need it:

echo date("Y-m-t", strtotime("next month")); //is 2020-08-13, return 2020-09-30
-1
function first_last_day($string, $first_last, $format) {
    $result = strtotime($string);
    $year = date('Y',$result);
    $month = date('m',$result);
    $result = strtotime("{$year}-{$month}-01");
    if ($first_last == 'last'){$result = strtotime('-1 second', strtotime('+1 month', $result)); }
    if ($format == 'unix'){return $result; }
    if ($format == 'standard'){return date('Y-m-d', $result); }
}

http://zkinformer.com/?p=134

kaiser
  • 21,817
  • 17
  • 90
  • 110
Kevin
  • 7
  • 1
-2

This a much more elegant way to get the end of the month:

  $thedate = Date('m/d/Y'); 
  $lastDayOfMOnth = date('d', mktime(0,0,0, date('m', strtotime($thedate))+1, 0, date('Y', strtotime($thedate)))); 
-3

You can use "t" in date function to get the number of day in a particular month.

The code will be something like this:

function lastDateOfMonth($Month, $Year=-1) {
    if ($Year < 0) $Year = 0+date("Y");
    $aMonth         = mktime(0, 0, 0, $Month, 1, $Year);
    $NumOfDay       = 0+date("t", $aMonth);
    $LastDayOfMonth = mktime(0, 0, 0, $Month, $NumOfDay, $Year);
    return $LastDayOfMonth;
}

for($Month = 1; $Month <= 12; $Month++)
    echo date("Y-n-j", lastDateOfMonth($Month))."\n";

The code is self-explained. So hope it helps.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
NawaMan
  • 25,129
  • 10
  • 51
  • 77