PHP using date() function to get numeric value for Sunday - Saturday - php

I am trying to get a numeric value (0-6) for the last day of the week in the month however it keeps returning a value of 3 when it in fact should be 4 for the month of 05-2018. Am I going about this in the wrong manner?
$endMonth = date('Y-m-t');
$dayPostition = date('w', $endMonth);

If you want to get the last on current month, you can:
$date = new DateTime("now");
$date->modify('last day of this month');
echo $date->format('w');
Or using a specific date
$date = new DateTime("2018-05-01"); //May 1, 2018
$date->modify('last day of this month');
echo $date->format('w');

The problem is that the second parameter of date() must be a timestamp rather than a string, and date() itself simply returns a string.
As such, you need to explicitly convert the first date() to a timestamp with strtotime():
$testvar = date('Y-m-t');
$lastDay = date('w', strtotime($testvar));
Which can be seen working here.

You are sending a string, not a date... try this
$endMonth = date('Y-m-t');
$dayPostition = date('w', strtotime($endMonth));

If you want to get the last day of month, you can use 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.
Try this
$getlastday = cal_days_in_month(CAL_GREGORIAN, 05, 2018);
$endMonth = date('2018-05-'.$getlastday);
$dayPostition = date('w', strtotime($endMonth));

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

php add x weeks to a date and then find the next given day

I can add x week to my date
//$ultima_azione <--- 2015/07/15
//$data['intervallo'] <---- 5
$mydate = date("Y-m-d",strtotime($ultima_azione." +".$data['intervallo']." weeks"));
now how can i give a day starting from that week
example:
//$mydate + "next Monday" -----> final date
and this ve to work like, if today is Monday and i add weeks to jump to an other Monday and then i select the next Monday the week don't ve to change
The simplest way would be to use strtotime. It can do date calculations based on a textual representation of the delta:
$mydate = strtotime('+3 weeks');
It also accepts a second parameter, which is a timestamp to start from when doing the calculation, so after you get the offset in weeks, you can pass the new date to a second calculation:
// Get three weeks from 'now' (no explicit time given)
$mydate = strtotime('+3 weeks');
// Get the Monday after that.
$mydate = strtotime('next Monday', $mydate);
See strtotime documentation for more examples of notations that you can use.
I would highly recommend using PHP's built-in DateTime class for any date and time logic. It's a much better API than the older date and time functions and creates much cleaner and easier to read code.
For example:
// Current date and number of weeks to add
$date = '2015/07/15';
$weeks = 3;
// Create and modify the date.
$dateTime = DateTime::createFromFormat('Y/m/d', $date);
$dateTime->add(DateInterval::createFromDateString($weeks . ' weeks'));
$dateTime->modify('next monday');
// Output the new date.
echo $dateTime->format('Y-m-d');
References:
DateTime.
DateTime::createFromFormat
DateTime::add
DateTime::modify
DateInterval::createFromDateString
DateTime::format
Are you looking for something like this?
$today = time();
$weeks = 2;
// timestamp 2 weeks from now
$futureWeeks = strtotime("+ ".$weeks." weeks");
// the next monday after the timestamp date
$futureMonday = strtotime("next monday",$futureWeeks);
echo date("Y-m-d", $futureMonday);
// or in one line
echo date("Y-m-d", strtotime("next monday", strtotime("+ ".$weeks." weeks")));
PHP is using an unix timestamp for date calculations. Functions as date() and strtotime() using a timestamp as an optional second parameter. This is used a reference for formatting and calculations. If no timestamp is passed to the function the current timestamp is used (time()).
I have the answer here. This will show the next wednesday every 2 weeks and the first date to start from would be the 10th.
I have also added in an estimated delivery which would be 6 weeks after that date.
We will be placing our next order for this on:
<?php
$date = '2020/05/26';
$weeks = 2;
$dateTime = DateTime::createFromFormat('Y/m/d', $date);
$dateTime->add(DateInterval::createFromDateString($weeks . ' weeks'));
$dateTime->modify('wednesday');
echo $dateTime->format('d/m/Y');
?>
Expected delivery for the next order will be:
<?php
$date = '2020/05/26';
$weeks = 2;
$dateTime = DateTime::createFromFormat('Y/m/d', $date);
$dateTime->add(DateInterval::createFromDateString($weeks . ' weeks'));
$dateTime->modify('+42 days next wednesday');
echo $dateTime->format('d/m/Y');
?>
If anyone can confirm this is correct that would be great.

Get the last day of the current year as date

How can I get the last day (Dec 31) of the current year as a date using PHP?
I tried the following but this doesn't work:
$year = date('Y');
$yearEnd = strtotime($year . '-12-31');
What I need is a date that looks like 2014-12-31 for the current year.
PHP strtotime() uses the current date/time as a basis (so it will use this current year), and you need date() to format:
$yearEnd = date('Y-m-d', strtotime('Dec 31'));
//or
$yearEnd = date('Y-m-d', strtotime('12/31'));
You can just concatenate actual year with required date
$year = date('Y') . '-12-31';
echo $year;
//output 2014-12-31
DateTime is perfectly capable of doing this:
$endOfYear = new \DateTime('last day of December this year');
You can even combine it with more modifiers to get the end of next year:
$endOfNextYear = new \DateTime('last day of December this year +1 years');
Another way to do this is use the Relative Formats of strtotime()
$yearEnd = date('Y-m-d', strtotime('last day of december this year'));
// or
$yearEnd = date('Y-m-d', strtotime('last day of december'));

Getting first / last date of the week

Is it possible to get the first / last date of a week using PHP's Relative Date Time format?
I've tried to do:
date_default_timezone_set('Europe/Amsterdam');
$date = new DateTime();
$date->modify('first day of this week'); // to get the current week's first date
echo $date->format('Y-m-d'); // outputs 2011-12-19
$date->modify('first day of week 50'); // to get the first date of any week by weeknumber
echo $date->format('Y-m-d'); // outputs 2011-12-18
$date->modify('last day of this week'); // to get the current week's last date
echo $date->format('Y-m-d'); // outputs 2011-12-17
$date->modify('last day of week 50'); // to get the last date of any week by weeknumber
echo $date->format('Y-m-d'); // outputs 2011-12-18
As you can see it doesn't output the correct dates.
According to the docs this should be possible if I'm correct.
Am I doing something terrible wrong?
EDIT
I need to use PHP's DateTime for dates in the far future.
UPDATE
It gets only stranger now. I've done some more testing.
Windows PHP 5.3.3
2011-12-01
Warning: DateTime::modify() [datetime.modify]: Failed to parse time string (first day of week 50) at position 13 (w): The timezone could not be found in the database in C:\Users\Gerrie\Desktop\ph\Websites\Charts\www.charts.com\public\index.php on line 9
2011-12-01
2011-11-30
Warning: DateTime::modify() [datetime.modify]: Failed to parse time string (last day of week 50) at position 12 (w): The timezone could not be found in the database in C:\Users\Gerrie\Desktop\ph\Websites\Charts\www.charts.com\public\index.php on line 15
2011-11-30
Linux 5.3.8
2011-12-01
2011-12-01
2011-11-30
2011-11-30
I'm a big fan of using the Carbon library, which makes this sort of thing really easy. For example:
use Carbon\Carbon;
$monday = Carbon::now()->startOfWeek()
$sunday = Carbon::now()->endOfWeek()
Or, if you'd prefer to have Sunday be the first day of your week:
use Carbon\Carbon;
Carbon::setWeekStartsAt(Carbon::SUNDAY);
Carbon::setWeekEndsAt(Carbon::SATURDAY);
$sunday = Carbon::now()->startOfWeek()
$saturday = Carbon::now()->endOfWeek()
According to docs the format strings "first day of" and "last day of" are only allowed for months, not for weeks. See http://www.php.net/manual/en/datetime.formats.relative.php
If you combine first and last day of with a week statement the result either blows the parser or is something that you did not expect (usually the first or last day of a month, not a week).
The difference that you see between Win and Linux is probably only because of different error reporting settings.
To get the first and last day of the current week use:
$date->modify('this week');
$date->modify('this week +6 days');
To get the first and last day of week 50 use:
$date->setISODate(2011, 50);
$date->setISODate(2011, 50, 7);
EDIT:
If you want to use the modify method for absolute week numbers you have to use the formats defined in http://www.php.net/manual/en/datetime.formats.compound.php:
$date->modify('2011W50');
$date->modify('2011W50 +6 days');
if first day of week is Monday
$date->modify('Monday this week');
else if first day is Sunday
$date->modify('Sunday this week');
because in different countries first day of week maybe Monday or Sunday
This is what I am using to get the first and last day of the week from any date.
In this case, monday is the first day of the week...
$date = date('Y-m-d'); // you can put any date you want
$nbDay = date('N', strtotime($date));
$monday = new DateTime($date);
$sunday = new DateTime($date);
$monday->modify('-'.($nbDay-1).' days');
$sunday->modify('+'.(7-$nbDay).' days');
function getweek_first_last_date($date)
{
$cur_date = strtotime($date); // Change to whatever date you need
// Get the day of the week: Sunday = 0 to Saturday = 6
$dotw = date('w', $cur_date);
if($dotw>1)
{
$pre_monday = $cur_date-(($dotw-1)*24*60*60);
$next_sunday = $cur_date+((7-$dotw)*24*60*60);
}
else if($dotw==1)
{
$pre_monday = $cur_date;
$next_sunday = $cur_date+((7-$dotw)*24*60*60);
}
else if($dotw==0)
{
$pre_monday =$cur_date -(6*24*60*60);;
$next_sunday = $cur_date;
}
$date_array = array();
$date_array['start_date_of_week'] = $pre_monday;
$date_array['end_date_of_week'] = $next_sunday;
return $date_array;
}
$date = '2013-12-22';
getweek_first_last_date($date);
Output :
$array_of_week = Array
(
[start_date_of_week] => 1387152000
[end_date_of_week] => 1387670400
)
$start_date =date('d/m/Y', $array_of_week['start_date_of_week'])
<code>
function getlastweek_first_last_date()
{
$cur_date = strtotime(date('Y-m-d')); // Change to whatever date you need
// Get the day of the week: Sunday = 0 to Saturday = 6
$previousweekcurdate = $cur_date - (7*24*3600);
$cur_date = $previousweekcurdate;
$dotw = date('w', $cur_date);
if($dotw>1)
{
$pre_sunday = $cur_date-(($dotw-1)*24*60*60) - (24*60*60);
$next_satday = $cur_date+((7-$dotw)*24*60*60)- (24*60*60);
}
else if($dotw==1)
{
$pre_sunday = $cur_date- (24*60*60);
$next_satday = $cur_date+((7-$dotw)*24*60*60)- (24*60*60);
}
else if($dotw==0)
{
$pre_sunday =$cur_date -(6*24*60*60)- (24*60*60);
$next_satday = $cur_date- (24*60*60);
}
$pre_sunday = date('Y-m-d',$pre_sunday)." 00:00:00";
$next_satday = date('Y-m-d',$next_satday)." 23:59:59";
$date_array = array();
$date_array['sdoflw'] = $pre_sunday;
$date_array['edoflw'] = $next_satday;
return $date_array;
}
$date_array = getlastweek_first_last_date();
echo $start_date_of_week = $date_array['sdoflw'];
echo $end_date_of_week = $date_array['edoflw'];
</code>
Simply you can get the date as follows
first day of week is Monday
date('Y-m-d',strtotime('Monday this week'));
if first day is Sunday
date('Y-m-d',strtotime('Sunday this week'));

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

Categories