Removing exactly one month from a date - php

It seems that you can't use strotime if you need reliable and accurate date manipulation. For example, if the month has 31 days, then it appears that strtotime simply minuses 30 days, not a whole month.
So, for example, if $event["EndDate"] is equal to "2013-10-31 00:00:01", the following code:
echo date("Y/n/j", strtotime('-1 month', strtotime($event["EndDate"]));
Ouputs: 2013/10/1 instead of 2013/09/30.
QUESTION: Now how I know how NOT to do it, is there another, more accurate, way to make PHP subtract (or add) exactly a whole month, and not just 30 days?

The main issue is that 2013/09/31 does not exist so a better approach would be to use first day or last day of the previous month.
$date = new DateTime("2013-10-31 00:00:01");
$date->modify("last day last month");
echo $date->format("Y/n/j"); // 2013/9/30
When date is 2013-10-15
$date = new DateTime("2013-10-15 00:00:01");
$day = $date->format("d");
$year = $date->format("Y");
$date->modify("last day last month");
$month = $date->format("m");
if (checkdate($month, $day, $year)) {
$date->setDate($year, $month, $day);
}
echo $date->format("Y/n/j"); // 2013-9-15

You say:-
It seems that you can't use strotime if you need reliable and accurate date manipulation
You can, you just need to know how it behaves. Your question prompted me to run a couple of tests.
PHP does not merely subtract 30 days from the date when subtracting a month, although it appears that it does from the single case you are looking at. In fact my test here suggests that it adds 31 days to the start of the previous month (the result of 3rd March suggests this to me) in this case.
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$oneMonth = new \DateInterval('P1M');
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = new \DateTime("2013-{$month}-31 00:00:01");
var_dump($date->format($format));
$date->sub($oneMonth);
var_dump($date->format($format));
}
There are 31 days between 2013-11-12 and 2013-10-12 and PHP calculates the month subtraction correctly as can be seen here.
$date = new \DateTime('2013-11-12 00:00:01');
var_dump($date);
$interval = new DateInterval('P1M');
$date->sub($interval);
var_dump($date);
In your particular case 2013-10-31 - 1 month is 2013-09-31 which does not exist. Any date/time function needs to return a valid date, which 2013-09-31 is not.
In this case PHP, as I stated above, seems to add 31 days to the start of the previous month to arrive at a valid date.
Once you know the expected behaviour, you can program accordingly. If the current behaviour does not fit your use case then you could extend the DateTime class to provide behaviour that works for you.
I have assumed that strtotime and DateTime::sub() behave the same, this test suggests they do.
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = date($format, strtotime('-1 month', strtotime("2013-{$month}-31 00:00:01")));
var_dump($date);
}

Related

Calculate date of last day of month before a target date

I can add any number of months to a date:
strtotime("+ 1 months", '2017-01-31') // result: 2017-03-03
But I want to do this without going to the next month.
in this case I want the result 2017-02-28, that is, the last day of the month before the target month.
There seems to be a lot of overcomplicating in these answers. You want the last day of the month before your target month, which is also always going to be 1 day before the first day of the target month. This can be expressed quite simply:
$months = 1;
$relativeto = '2017-01-31';
echo date(
'Y-m-d',
strtotime(
'-1 day',
strtotime(
date(
'Y-m-01',
strtotime("+ $months months", strtotime($relativeto))
)
)
)
);
Try using the DateTime object like so:
$dateTime = new \DateTime('2017-01-31');
$dateTime->add(new \DateInterval('P1M'));
$result = $dateTime->format('Y-m-d');
Use PHP's DateTime to accomplish this, specifically the modify() method.
$date = new DateTime('2006-12-12');
$date->modify('+1 month');
echo $date->format('Y-m-d');
If the idea here is not to allow the date to overflow into the next month, which PHP does, then you'll have to impose that constraint in your logic.
One approach is to check the modified month against the given month before returning the updated date.
function nextMonth(DateTimeImmutable $date) {
$nextMonth = $date->add(new DateInterval("P1M"));
$diff = $nextMonth->diff($date);
if ($diff->d > 0) {
$nextMonth = $nextMonth->sub(new DateInterval("P{$diff->d}D"));
}
return $nextMonth;
}
$date = new DateTimeImmutable("2017-01-31");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
//2017-01-31 - 2017-02-28
$date = new DateTimeImmutable("2017-10-31");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
//2017-10-31 - 2017-11-30
The nextMonth() function in the example above, imposes the constraint of not overflowing into the next month. Note that what PHP actually does is try to find the corresponding day, in the following consecutive number of months added, not just add a given number of months to the existing date. I simply undo this last part by subtracting any additional days beyond the 1 month interval in the function above.
So for example, strtotime("+1 month") for the date "2017-01-31", tells PHP find the 31st day that is +1 month from "2017-01-31". But of course, there are only 28 days in February, so PHP goes into March and counts up 3 more days to compensate.
In other words, it's not just add +1 month to this date, but add +1 month to this date and arrive at the same day of the month as is in the given date. Which is where the overflow happens.
Update
Since you've now made it clear that you actually want the last day of the month (not necessarily the same day of the next month without the overflow provision) you should instead just explicitly set the day of the month.
function nextMonth(DateTimeImmutable $date) {
$nextMonth = $date->setDate($date->format('Y'), $date->format('n') + 1, 1);
$nextMonth = $date->setDate($nextMonth->format('Y'), $nextMonth->format('n'), $nextMonth->format('t'));
return $nextMonth;
}
$date = new DateTimeImmutable("2017-02-28");
$nextMonth = nextMonth($date);
echo "{$date->format('Y-m-d')} - {$nextMonth->format('Y-m-d')}\n";
// 2017-02-28 - 2017-03-31

How do I remove 3 months from a date?

Assume the date is:
$date = "2011-08-28";
It need to calculate 3 months previous to $date - how can that be done?
$new_timestamp = strtotime('-3 months', strtotime($date));
You can then use the new timestamp with the php date() function to display the new date how you wish, for example:
echo date("Y-m-d",$new_timestamp);
For me this way is much better because the code is more readable.
$datetime = Datetime::createFromFormat('Y-m-d', "2011-08-28");
$datetime->modify('-3 months');
echo $datetime->format('Y-m-d');
edit: I'm an idiot. You could do the above as follows
$datetime = new Datetime("2011-08-28");
$datetime->modify('-3 months');
echo $datetime->format('Y-m-d');
edit: As pointed out by calumbrodie, you can use the sub method instead of inverting the interval and adding it to the date object
I was trying to do something similar to the original question. I needed to subtract 1 day from a DateTime object. I know the other solutions work, but here's another way I liked better. I used this function:
function getPreviousDay($dateObject){
$interval = new DateInterval('P1D');
$dateObject->sub($interval);
return $dateObject;
}
$dateObject is a DateTime object that can have any date you wan't, but as I wanted the current date, I wrote:
$dateObject = new DateTime('now');
What my function does, is subtract 1 day from the date it receives, but you can modify it so it subtracts 3 months modifying the DateInterval constructor like this:
$interval = new DateInterval('P3M');
$dateObject->sub($interval);
return $dateObject;
You can find the explanation on the string format used in the DateInterval constructor here
DateInterval constructor documentation
There you'll se that letter 'P' (period) is mandatory, the you use an int to specify period length and then specify the period type, in the case of months 'M'. It looks as if there was an error in the documentation, it says that "M" is used for months and minutes, but it actually works for months. If you need to use minutes, you must specify "PTM", for example "PT3M" for 3 minutes, outside the table it says you must use the "T" identifier for time intervals.
edit:
To give a complete example, you have to use this format for a full date time interval:
$format = 'P1Y2M4DT2H1M40S';
This will represent an interval of 1 year, 2 months, 4 days, 2 hours,1 minute and 40 seconds
Hope this helps someone
<?php
$threemonthsago = mktime(0, 0, 0, date("m")-3, date("d"), date("Y"));
?>
<?php
$date = date_create('2000-01-01');
date_add($date, date_interval_create_from_date_string('10 days'));
echo date_format($date, 'Y-m-d');
?>

How to get previous month and year relative to today, using strtotime and date?

I need to get previous month and year, relative to current date.
However, see following example.
// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));
// Output:
2011-03-02
This behavior is understandable (to a certain point), due to different number of days in february and march, and code in example above is what I need, but works only 100% correctly for between 1st and 28th of each month.
So, how to get last month AND year (think of date("Y-m")) in the most elegant manner as possible, which works for every day of the year? Optimal solution will be based on strtotime argument parsing.
Update. To clarify requirements a bit.
I have a piece of code that gets some statistics of last couple of months, but I first show stats from last month, and then load other months when needed. That's intended purpose. So, during THIS month, I want to find out which month-year should I pull in order to load PREVIOUS month stats.
I also have a code that is timezone-aware (not really important right now), and that accepts strtotime-compatible string as input (to initialize internal date), and then allows date/time to be adjusted, also using strtotime-compatible strings.
I know it can be done with few conditionals and basic math, but that's really messy, compared to this, for example (if it worked correctly, of course):
echo tz::date('last month')->format('Y-d')
So, I ONLY need previous month and year, in a strtotime-compatible fashion.
Answer (thanks, #dnagirl):
// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01
Have a look at the DateTime class. It should do the calculations correctly and the date formats are compatible with strttotime. Something like:
$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02
if the day itself doesn't matter do this:
echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));
I found an answer as I had the same issue today which is a 31st. It's not a bug in php as some would suggest, but is the expected functionality (in some since). According to this post what strtotime actually does is set the month back by one and does not modify the number of days. So in the event of today, May 31st, it's looking for April-31st which is an invalid date. So it then takes April 30 an then adds 1 day past it and yields May 1st.
In your example 2011-03-30, it would go back one month to February 30th, which is invalid since February only has 28 days. It then takes difference of those days (30-28 = 2) and then moves two days past February 28th which is March 2nd.
As others have pointed out, the best way to get "last month" is to add in either "first day of" or "last day of" using either strtotime or the DateTime object:
// Today being 2012-05-31
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d');
// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month"));
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');
So using these it's possible to create a date range if your making a query etc.
If you want the previous year and month relative to a specific date and have DateTime available then you can do this:
$d = new \DateTimeImmutable('2013-01-01', new \DateTimeZone('UTC'));
$firstDay = $d->modify('first day of previous month');
$year = $firstDay->format('Y'); //2012
$month = $firstDay->format('m'); //12
date('Y-m', strtotime('first day of last month'));
strtotime have second timestamp parameter that make the first parameter relative to second parameter. So you can do this:
date('Y-m', strtotime('-1 month', time()))
if i understand the question correctly you just want last month and the year it is in:
<?php
$month = date('m');
$year = date('Y');
$last_month = $month-1%12;
echo ($last_month==0?($year-1):$year)."-".($last_month==0?'12':$last_month);
?>
Here is the example: http://codepad.org/c99nVKG8
ehh, its not a bug as one person mentioned. that is the expected behavior as the number of days in a month is often different. The easiest way to get the previous month using strtotime would probably be to use -1 month from the first of this month.
$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));
I think you've found a bug in the strtotime function. Whenever I have to work around this, I always find myself doing math on the month/year values. Try something like this:
$LastMonth = (date('n') - 1) % 12;
$Year = date('Y') - !$LastMonth;
date("m-Y", strtotime("-1 months"));
would solve this
Perhaps slightly more long winded than you want, but i've used more code than maybe nescessary in order for it to be more readable.
That said, it comes out with the same result as you are getting - what is it you want/expect it to come out with?
//Today is whenever I want it to be.
$today = mktime(0,0,0,3,31,2011);
$hour = date("H",$today);
$minute = date("i",$today);
$second = date("s",$today);
$month = date("m",$today);
$day = date("d",$today);
$year = date("Y",$today);
echo "Today: ".date('Y-m-d', $today)."<br/>";
echo "Recalulated: ".date("Y-m-d",mktime($hour,$minute,$second,$month-1,$day,$year));
If you just want the month and year, then just set the day to be '01' rather than taking 'todays' day:
$day = 1;
That should give you what you need. You can just set the hour, minute and second to zero as well as you aren't interested in using those.
date("Y-m",mktime(0,0,0,$month-1,1,$year);
Cuts it down quite a bit ;-)
This is because the previous month has less days than the current month. I've fixed this by first checking if the previous month has less days that the current and changing the calculation based on it.
If it has less days get the last day of -1 month else get the current day -1 month:
if (date('d') > date('d', strtotime('last day of -1 month')))
{
$first_end = date('Y-m-d', strtotime('last day of -1 month'));
}
else
{
$first_end = date('Y-m-d', strtotime('-1 month'));
}
If a DateTime solution is acceptable this snippet returns the year of last month and month of last month avoiding the possible trap when you run this in January.
function fn_LastMonthYearNumber()
{
$now = new DateTime();
$lastMonth = $now->sub(new DateInterval('P1M'));
$lm= $lastMonth->format('m');
$ly= $lastMonth->format('Y');
return array($lm,$ly);
}
//return timestamp, use to format month, year as per requirement
function getMonthYear($beforeMonth = '') {
if($beforeMonth !="" && $beforeMonth >= 1) {
$date = date('Y')."-".date('m')."-15";
$timestamp_before = strtotime( $date . ' -'.$beforeMonth.' month' );
return $timestamp_before;
} else {
$time= time();
return $time;
}
}
//call function
$month_year = date("Y-m",getMonthYear(1));// last month before current month
$month_year = date("Y-m",getMonthYear(2)); // second last month before current month
function getOnemonthBefore($date){
$day = intval(date("t", strtotime("$date")));//get the last day of the month
$month_date = date("y-m-d",strtotime("$date -$day days"));//get the day 1 month before
return $month_date;
}
The resulting date is dependent to the number of days the input month is consist of. If input month is february (28 days), 28 days before february 5 is january 8. If input is may 17, 31 days before is april 16. Likewise, if input is may 31, resulting date will be april 30.
NOTE: the input takes complete date ('y-m-d') and outputs ('y-m-d') you can modify this code to suit your needs.

PHP get start and end date of a week by weeknumber

I've seen some variants on this question but I believe this one hasn't been answered yet.
I need to get the starting date and ending date of a week, chosen by year and week number (not a date)
example:
input:
getStartAndEndDate($week, $year);
output:
$return[0] = $firstDay;
$return[1] = $lastDay;
The return value will be something like an array in which the first entry is the week starting date and the second being the ending date.
OPTIONAL: while we are at it, the date format needs to be Y-n-j (normal date format, no leading zeros.
I've tried editing existing functions that almost did what I wanted but I had no luck so far.
Using DateTime class:
function getStartAndEndDate($week, $year) {
$dto = new DateTime();
$dto->setISODate($year, $week);
$ret['week_start'] = $dto->format('Y-m-d');
$dto->modify('+6 days');
$ret['week_end'] = $dto->format('Y-m-d');
return $ret;
}
$week_array = getStartAndEndDate(52,2013);
print_r($week_array);
Returns:
Array
(
[week_start] => 2013-12-23
[week_end] => 2013-12-29
)
Explained:
Create a new DateTime object which defaults to now()
Call setISODate to change object to first day of $week of $year instead of now()
Format date as 'Y-m-d' and put in $ret['week_start']
Modify the object by adding 6 days, which will be the end of $week
Format date as 'Y-m-d' and put in $ret['week_end']
A shorter version (works in >= php5.3):
function getStartAndEndDate($week, $year) {
$dto = new DateTime();
$ret['week_start'] = $dto->setISODate($year, $week)->format('Y-m-d');
$ret['week_end'] = $dto->modify('+6 days')->format('Y-m-d');
return $ret;
}
Could be shortened with class member access on instantiation in >= php5.4.
Many years ago, I found this function:
function getStartAndEndDate($week, $year) {
$dto = new DateTime();
$dto->setISODate($year, $week);
$ret['week_start'] = $dto->format('Y-m-d');
$dto->modify('+6 days');
$ret['week_end'] = $dto->format('Y-m-d');
return $ret;
}
$week_array = getStartAndEndDate(52,2013);
print_r($week_array);
We can achieve this easily without the need for extra computations apart from those inherent to the DateTime class.
function getStartAndEndDate($year, $week)
{
return [
(new DateTime())->setISODate($year, $week)->format('Y-m-d'), //start date
(new DateTime())->setISODate($year, $week, 7)->format('Y-m-d') //end date
];
}
The setISODate() function takes three arguments: $year, $week, and $day respectively, where $day defaults to 1 - the first day of the week. We therefore pass 7 to get the exact date of the 7th day of the $week.
Slightly neater solution, using the "[year]W[week][day]" strtotime format:
function getStartAndEndDate($week, $year) {
// Adding leading zeros for weeks 1 - 9.
$date_string = $year . 'W' . sprintf('%02d', $week);
$return[0] = date('Y-n-j', strtotime($date_string));
$return[1] = date('Y-n-j', strtotime($date_string . '7'));
return $return;
}
shortest way to do it:
function week_date($week, $year){
$date = new DateTime();
return "first day of the week is ".$date->setISODate($year, $week, "1")->format('Y-m-d')
."and last day of the week is ".$date->setISODate($year, $week, "7")->format('Y-m-d');
}
echo week_date(12,2014);
You can get the specific day of week from date as bellow that I get the first and last day
$date = date_create();
// get the first day of the week
date_isodate_set($date, 2019, 1);
//convert date format and show
echo date_format($date, 'Y-m-d') . "\n";
// get the last date of the week
date_isodate_set($date, 2019, 1, 7);
//convert date format and show
echo date_format($date, 'Y-m-d') . "\n";
Output =>
2018-12-31
2019-01-06
The calculation of Roham Rafii is wrong. Here is a short solution:
// week number to timestamp (first day of week number)
function wn2ts($week, $year) {
return strtotime(sprintf('%dW%02d', $year, $week));
}
if you want the last day of the week number, you can add up 6 * 24 * 3600
This is an old question, but many of the answers posted above appear to be incorrect.
I came up with my own solution:
function getStartAndEndDate($week, $year){
$dates[0] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT)));
$dates[1] = date("Y-m-d", strtotime($year.'W'.str_pad($week, 2, 0, STR_PAD_LEFT).' +6 days'));
return $dates;
}
First we need a day from that week so by knowing the week number and knowing that a week has seven days we are going to do so the
$pickADay = ($weekNo-1) * 7 + 3;
this way pickAday will be a day in our desired week.
Now because we know the year we can check which day is that.
things are simple if we only need dates newer than unix timestamp
We will get the unix timestamp for the first day of the year and add to that 24*3600*$pickADay and all is simple from here because we have it's timestamp we can know what day of the week it is and calculate the head and tail of that week accordingly.
If we want to find out the same thing of let's say 12th week of 1848 we must use another approach as we can not get the timestamp. Knowing that each year a day advances 1 weekday meaning (1st of november last year was on a sunday, this year is on a monday, exception for the leap years when it advances 2 days I believe, you can check that ). What I would do if the year is older than 1970 than make a difference between it and the needed year to know how many years are there, calculate the day of the week as my pickADay was part of 1970, shift it back one weekday for each. $shiftTimes = ($yearDifference + $numberOfLeapYears)%7, in the difference. shift the day backwords $shiftTimes, then you will know what day of the week was that day those years ago, then find the weekhead and weektail. Same thing can be used also for the future if it seems simpler. Try it if it works and tell me if it does not.
For documentation (since Google ranks this question first when searching for "php datetime start end this week").
If you need the startdate and enddate for the current week (using DateTime):
$dateTime = new DateTime('now');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');
var_dump($monday->format('Y-m-d')); // e.g. 2018-06-25
var_dump($sunday->format('Y-m-d')); // e.g. 2018-07-01
Hope this will help.
The "first day of the week" is subjective. Some cultures use "Monday" others "Sunday", maybe others something else?
For my purposes, I want the first day of the week to be "Sunday" and the last day of the week to be "Saturday".
Also, using DateTime with no arguments will default to "now" which includes the current time. The following method will disregard the current time by specifying "today" in the DateTime constructor.
Furthermore the string "sunday this week" does not seem to be reliable. It actually will return Sunday the next week (according to my view of what a week is).
I've built a method which returns a PHP object containing two DateTime objects. One for the first day (Sunday) of the given week, the second for the last day (Saturday) of the given week.
function get_first_and_last_day_of_week( $year_number, $week_number ) {
// we need to specify 'today' otherwise datetime constructor uses 'now' which includes current time
$today = new DateTime( 'today' );
return (object) [
'first_day' => clone $today->setISODate( $year_number, $week_number, 0 ),
'last_day' => clone $today->setISODate( $year_number, $week_number, 6 )
];
}
Have you tried PHP relative dates? It might work.
Even if you dont want to use a specific date you cannot escape it. You can calculate a week based on the date ONLY.
Steps:
get the first day of the year
decide when the first week starts ( there are some rules that include first Thursday if I remember.
add some number of weeks (your first param). Zend_Date has an add() function where you can add weeks for example. This will give you the first day of the week.
offset and get the last day.
I would recommend working with a consistent dates sistem like Zend_Date or Pear Date.
function getStartAndEndDate($week, $year)
{
$week_start = new DateTime();
$week_start->setISODate($year,$week);
$return[0] = $week_start->format('d-M-Y');
$time = strtotime($return[0], time());
$time += 6*24*3600;
$return[1] = date('d-M-Y', $time);
return $return;
}
$dateParam = '2018-06-10';
$week = date('w', strtotime($dateParam));
$date = new DateTime($dateParam);
$firstWeek = $date->modify("-".$week." day")->format("Y-m-d H:i:s");
$endWeek = $date->modify("+6 day")->format("Y-m-d H:i:s");
echo $firstWeek."<br/>";
echo $endWeek;
will print
2018-06-10 00:00:00
2018-06-16 00:00:00
hopefully will help

how to get the date of last week's (tuesday or any other day) in php?

I think its possible but i cant come up with the right algorithm for it.
What i wanted to do was:
If today is monday feb 2 2009, how would i know the date of last week's tuesday? Using that same code 2 days after, i would find the same date of last week's tuesday with the current date being wednesday, feb 4 2009.
Most of these answers are either too much, or technically incorrect because "last Tuesday" doesn't necessarily mean the Tuesday from last week, it just means the previous Tuesday, which could be within the same week of "now".
The correct answer is:
strtotime('tuesday last week')
I know there is an accepted answer already, but imho it does not meet the second requirement that was asked for. In the above case, strtotime would yield yesterday if used on a wednesday. So, just to be exact you would still need to check for this:
$tuesday = strtotime('last Tuesday');
// check if we need to go back in time one more week
$tuesday = date('W', $tuesday)==date('W') ? $tuesday-7*86400 : $tuesday;
As davil pointed out in his comment, this was kind of a quick-shot of mine. The above calculation will be off by one once a year due to daylight saving time. The good-enough solution would be:
$tuesday = date('W', $tuesday)==date('W') ? $tuesday-7*86400+7200 : $tuesday;
If you need the time to be 0:00h, you'll need some extra effort of course.
PHP actually makes this really easy:
echo strtotime('last Tuesday');
See the strtotime documentation.
Working solution:
$z = date("Y-m-d", strtotime("last Saturday"));
$z = (date('W', strtotime($z)) == date('W')) ? (strtotime($z)-7*86400+7200) : strtotime($z);
print date("Y-m-d", $z);
you forgot strtotime for second argument of date('W', $tuesday)
hmm.
convert $tuesday to timestamp before "$tuesday-7*86400+7200"
mde.
// test: find last date for each day of the week
foreach (array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun') as $day) {
print $day . " => " . date('m/d/Y', last_dayofweek($day)) . "\n";
}
function last_dayofweek($day)
{
// return timestamp of last Monday...Friday
// will return today if today is the requested weekday
$day = strtolower(substr($day, 0, 3));
if (strtolower(date('D')) == $day)
return strtotime("today");
else
return strtotime("last {$day}");
}
<?php
$currentDay = date('D');
echo "Today-".$today = date("Y-m-d");
echo "Yesterday-".$yesterday = date("Y-m-d",strtotime('yesterday'));
echo "Same day last week-".$same_day_last_week = date("Y-m-d",strtotime('last '.$currentDay));
?>
Do not use manual calculation, use DateTime object instead. It has proper implementation, takes into account leap years, yeap seconds, etc.
$today = new \DateTime();
$today->modify('tuesday last week');
The modify method modifies the date relative to it's state, so if you set the date to a different date, it calculates it relative to it.
$date = new \DateTime('2020-01-01');
echo $date->format('Y-m-d'); // 2020-01-01
$date->modify('tuesday last week');
echo $date->format('Y-m-d'); // 2019-12-24

Categories