PHP How to divide weeks into days - php

How to enlist all the days between for instance 2018-06-04 and 2018-06-10 that between 2018-06-04 - 2018-06-10 those days will be 2018-06-05, 2018-06-06, 2018-06-07, 2018-06-08, 2018-06-09, the same goes for 2018-06-11 - 2018-06-17 and so on...
So far I'ive managed to divide month into week chunks (below), I want to further divide weeks into days...
2018-06-04 - 2018-06-10
2018-06-11 - 2018-06-17
2018-06-18 - 2018-06-24
2018-06-25 - 2018-07-01
http://zakodowac.pl/
This is my PHP code which produces week chunks above 2018-06-04 - 2018-06-10 and so on...:
function getMondays($y, $m) {
return new DatePeriod(
new DateTime("first monday of $y-$m"),
DateInterval::createFromDateString('next monday'),
new DateTime("last day of $y-$m")
);
}
function list_week_days($year, $month) {
foreach (getMondays($year, $month) as $monday) {
echo $monday->format(" Y-m-d\n");
echo '-';
$sunday = $monday->modify('next Sunday');
echo $sunday->format(" Y-m-d\n");
echo '<br>';
}
}
list_week_days(2018, 06);

could you try this:
$begin = strtotime('2018-06-04');
$end = strtotime('2018-06-10');
while($begin < $end){
$begin = $begin +84600;
echo date('Y-m-d', $begin) . ' ';
}

if correctly understood, then the following should yield the results you expect:
// set current date
$date = '04/30/2009';
// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime($date);
// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 1;
if ($offset < 0) {
$offset = 6;
}
// calculate timestamp for the Monday
$ts = $ts - $offset*86400;
// loop from Monday till Sunday
for ($i = 0; $i < 7; $i++, $ts += 86400){
print date("m/d/Y l", $ts) . "\n";
}
if you want to be even more clever, you can use:
// set current date
$date = '04/30/2009';
// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime($date);
// find the year (ISO-8601 year number) and the current week
$year = date('o', $ts);
$week = date('W', $ts);
// print week for the current date
for($i = 1; $i <= 7; $i++) {
// timestamp from ISO week date format
$ts = strtotime($year.'W'.$week.$i);
print date("m/d/Y l", $ts) . "\n";
}
All of which, alongside more information, can be found on this website and credit goes to the author of that post.

Related

PHP: Loop through all weeks in a date range (last 2 years)?

I like to iterate through all weeks in a date range that spawns 2 years. Starting at the current week number two years ago, until the current week number this year.
The problem is that a year can either have 52 weeks or 53 weeks, for example:
2015 had 53 weeks (the 53th was from 2015-12-28 till 2016-01-03)
2016 had 52 weeks (the 52th was from 2016-12-26 till 2017-01-01)
So this is currently my php code:
# start with the current week 2 years ago
$year = date("Y") - 2;
$week = (int) date("W"); // (int) removes leading zero for weeks < 10
$endYear = date("Y");
$endWeek = (int) date("W");
# iterate through all weeks until now
do {
echo $week. " of ". $year;
$week++;
if ($week > 52) { // or greater 53 ?????????????
$year ++;
$week = 1;
}
}
while ($year < $endYear || $week < $endWeek);
Instead of trying to keep track of the bounds, let PHP do it for you.
$start = new DateTime('-2 years');
$end = new DateTime();
$interval = new DateInterval('P1W');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $date) {
echo $date->format('W') . " of ". $date->format('Y') . "\n";
}
Demo
With the help of Ross Wilson and John Conde I found a solution:
$now = new DateTime;
$from = (new DateTime)->setISODate($now->format('Y') - 2, $now->format('W'));
$from->modify("thursday this week"); // see ISO 8601
while($from < $now) {
echo $from->format('W Y').'<br />';
$from->modify("+1 week");
}
It is important so set the week day to thursday, because according to ISO 8601, the week "belongs" to the year which still contains the thursday.
You could use DateTime and setISODate for something like this:
$now = new DateTime;
$from = (new DateTime)->setISODate($now->format('Y') - 2, $now->format('W'));
while($from < $now) {
echo $from->format('W Y').'<br />';
$from->modify("1 week");
}
Hope this helps!

How to show week list for the specific date and week start from sunday

I have week list dates logic from the specific date which returns following results.
12/05/2016 Monday
12/06/2016 Tuesday
12/07/2016 Wednesday
12/08/2016 Thursday
12/09/2016 Friday
12/10/2016 Saturday
12/11/2016 Sunday
Logic:
// set current date
$date = '12/08/2016';
// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime($date);
// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 1;
if ($offset < 0) {
$offset = 6;
}
// calculate timestamp for the Monday
$ts = $ts - $offset*86400;
// loop from Monday till Sunday
for ($i = 0; $i < 7; $i++, $ts += 86400){
print date("m/d/Y l", $ts) . "\n";
echo "<br>";
}
Currently getting days from Monday to Sunday but don't know how to start a week from Sunday?
Replace "1" with "0".
$offset = $dow - 0;

PHP: DatePeriod with last day of month

I'd like to work with PHP DateInterval to iterate through months:
$from = new DateTime();
$from->setDate(2014, 1, 31);
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
I'd expect it to returns 31 January, 28 February (as the DateInterval is 1 month), but it actually returns 31 January, 3 March, 3 of April... hence skipping February.
Is there any way to do this simply?
Thanks!
EDIT : as a refernece, here is a solution that seems to cover most use cases:
$date = new DateTime('2014-01-31');
$start = $date->format('n');
for ($i = 0; $i < 28; $i++) {
$current = clone $date;
$current->modify('+'.$i.' month');
if ($current->format('n') > ($start % 12) && $start !== 12) {
$current->modify('last day of last month');
}
$start++;
echo $current->format('Y-m-d').PHP_EOL;
}
You can use DateTime::modify():
$date = new DateTime('last day of january');
echo $date->format('Y-m-d').PHP_EOL;
for ($i = 1; $i < 12; $i++) {
$date->modify('last day of next month');
echo $date->format('Y-m-d').PHP_EOL;
}
EDIT: I think I didn't understand your question clearly. Here is a new version:
$date = new DateTime('2014-01-31');
for ($i = 0; $i < 12; $i++) {
$current = clone $date;
$current->modify('+'.$i.' month');
if ($current->format('n') > $i + 1) {
$current->modify('last day of last month');
}
echo $current->format('Y-m-d').PHP_EOL;
}
The issue is cause by the variance between the last day in each of the months within the range. ie. February ending on 28 instead of 31 and the addition of 1 month from the last day 2014-01-31 + 1 month = 2014-03-03 https://3v4l.org/Y42QJ
To resolve the issue with DatePeriod and simplify it a bit, adjust the initial date by resetting the specified date to the first day of the specified month, by using first day of this month.
Then during iteration, you can modify the date period date by using last day of this month to retrieve the bounds of the currently iterated month.
Example: https://3v4l.org/889mB
$from = new DateTime('2014-01-31');
$from->modify('first day of this month'); //2014-01-01
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
echo $date->modify('last day of this month')->format('Y-m-d');
}
Result:
2014-01-31
2014-02-28
2014-03-31
2014-04-30
2014-05-31
2014-06-30
2014-07-31
2014-08-31
2014-09-30
2014-10-31
2014-11-30
2014-12-31
2015-01-31
Then to expand on this approach, in order to retrieve the desired day from the specified date, such as the 29th. You can extract the specified day and adjust the currently iterated month as needed when the day is out of bounds for that month.
Example: https://3v4l.org/SlEJc
$from = new DateTime('2014-01-29');
$day = $from->format('j');
$from->modify('first day of this month'); //2014-01-01
$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
$lastDay = clone $date;
$lastDay->modify('last day of this month');
$date->setDate($date->format('Y'), $date->format('n'), $day);
if ($date > $lastDay) {
$date = $lastDay;
}
echo $date->format('Y-m-d');
}
Result:
2014-01-29
2014-02-28 #notice the last day of february is used
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
2014-08-29
2014-09-29
2014-10-29
2014-11-29
2014-12-29
2015-01-29
You may try like this:
$date = new DateTime();
$lastDayOfMonth = $date->modify(
sprintf('+%d days', $date->format('t') - $date->format('j'))
);
I would do it probably like this
$max = array (
31,28,31,30,31,30,31,31,30,31,30,31
); //days in month
$month = 1;
$year = 2014;
$day = 31;
$iterate = 12;
$dates = array();
for ($i = 0;$i < $iterate;$i++) {
$tmp_month = ($month + $i) % 12;
$tmp_year = $year + floor($month+$i)/12;
$tmp_day = min($day, $max[$tmp_month]);
$tmp = new DateTime();
$tmp->setDate($tmp_year, $tmp_month + 1, $tmp_day);
$dates[] = $tmp;
}
var_dump($dates);
This keeps to the same day each month if possible

Find the week start and end dates of all weeks between two week numbers

I am trying to get the start date and end dates of all weeks between two week numbers.
That is one of my date is 2014-05-17 and its week number is 20 and other date is 2014-08-13 and its week number is 33.
My task is to get start and end dates of all weeks between 20 and 33. Here Sunday is the week start and Saturday week end.
$signupweek='2014-05-17';
$signupweek=date("W",strtotime($signupdate));
//week number of current date.
$weekNumber = date("W");
Can anyone help to find the dates.
try this
$signupdate='2014-05-17';
$signupweek=date("W",strtotime($signupdate));
$year=date("Y",strtotime($signupdate));
$currentweek = date("W");
for($i=$signupweek;$i<=$currentweek;$i++) {
$result=getWeek($i,$year);
echo "Week:".$i." Start date:".$result['start']." End date:".$result['end']."<br>";
}
function getWeek($week, $year) {
$dto = new DateTime();
$result['start'] = $dto->setISODate($year, $week, 0)->format('Y-m-d');
$result['end'] = $dto->setISODate($year, $week, 6)->format('Y-m-d');
return $result;
}
Output
Week:20 Start date:2014-05-11 End date:2014-05-17
Week:21 Start date:2014-05-18 End date:2014-05-24
Week:22 Start date:2014-05-25 End date:2014-05-31
Week:23 Start date:2014-06-01 End date:2014-06-07
Week:24 Start date:2014-06-08 End date:2014-06-14
Week:25 Start date:2014-06-15 End date:2014-06-21
Week:26 Start date:2014-06-22 End date:2014-06-28
Week:27 Start date:2014-06-29 End date:2014-07-05
Week:28 Start date:2014-07-06 End date:2014-07-12
Week:29 Start date:2014-07-13 End date:2014-07-19
Week:30 Start date:2014-07-20 End date:2014-07-26
Week:31 Start date:2014-07-27 End date:2014-08-02
Week:32 Start date:2014-08-03 End date:2014-08-09
Week:33 Start date:2014-08-10 End date:2014-08-16
Another method...
If you have a date, from that date you can find the start date and end date of that week. But here week number is not used.
For example:
You have a date 2014-08-13, then required start date is 2014-08-10 and end date is 2014-08-16.
PHP code is
$signupweek='2014-8-13';
/*start day*/
for($i = 0; $i <7 ; $i++)
{
$date = date('Y-m-d', strtotime("-".$i."days", strtotime($signupweek)));
$dayName = date('D', strtotime($date));
if($dayName == "Sun")
{
echo "start day is ". $date."<br>";
}
}
/*end day*/
for($i = 0; $i <7 ; $i++)
{
$date = date('Y-m-d', strtotime("+".$i."days", strtotime($signupweek)));
$dayName = date('D', strtotime($date));
if($dayName == "Sat")
{
echo "end day is ". $date."<br>";
}
}
OUTPUT
start day is 2014-08-10
end day is 2014-08-16
Hope this is useful..
Here's an example that implements the function from this answer:
$signupweek = '2014-05-17';
$signupweek = date("W", strtotime($signupweek));
$current_week = date('W');
$output = array();
// Loop through the weeks BETWEEN your given weeks
// to include the start and end week, remove the +1 below and make
// it $i <= $current_week
for($i = $signupweek + 1; $i < $current_week; $i++) {
// Get the start and end for the current week ($i)
$dates = getStartAndEndDate($i, '2014');
// if the start or end of the week is greater than now, skip it
if(strtotime($dates['start']) > time() or strtotime($dates['end']) > time())
continue;
// Add to output array
$output[] = $dates;
}
function getStartAndEndDate($week, $year)
{
$time = strtotime("1 January $year", time());
$day = date('w', $time);
$time += ((7 * $week) + 1 - $day) * 24 * 3600;
$return['start'] = date('Y-n-j', $time);
$time += 6 * 24 * 3600;
$return['end'] = date('Y-n-j', $time);
return $return;
}
Output
Try this:
$startTime = "2014-05-17";
$startWeek = 20;
$endWeek = 33;
for ($i = 0; $i <= ($endWeek - $startWeek); $i++) {
$days = $i * 7;
echo date("Y-m-d", strtotime($startTime . "+$days day")).'<br />';
}
Unfortunately, it seems that 2014-08-13 is not the start of week 33. 2014-08-16 is.
You can now use DateTime to get start/end dates of week(s)
function getDateRangeForAllWeeks($start, $end){
$fweek = getDateRangeForWeek($start);
$lweek = getDateRangeForWeek($end);
$week_dates = [];
while($fweek['sunday']!=$lweek['sunday']){
$week_dates [] = $fweek;
$date = new DateTime($fweek['sunday']);
$date->modify('next day');
$fweek = getDateRangeForWeek($date->format("Y-m-d"));
}
$week_dates [] = $lweek;
return $week_dates;
}
function getDateRangeForWeek($date){
$dateTime = new DateTime($date);
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
$sunday = clone $dateTime->modify('Sunday this week');
return ['monday'=>$monday->format("Y-m-d"), 'sunday'=>$sunday->format("Y-m-d")];
}
print_r( getDateRangeForWeek("2016-05-07") );
print_r( getDateRangeForAllWeeks("2015-11-07", "2016-02-15") );

PHP- Display days weekly by giving 2 dates

I'd like display dates by week number between giving 2 dates like example below. Is this possible in PHP?
if the dates are 2010-12-01 thru 2010-12-19, it will display it as follows.
week-1
2010-12-01
2010-12-02
2010-12-03
2010-12-04
2010-12-05
2010-12-06
2010-12-07
week-2
2010-12-08
2010-12-09
2010-12-10
2010-12-11
2010-12-12
2010-12-13
2010-12-14
week-3
2010-12-15
2010-12-16
2010-12-17
2010-12-18
2010-12-19
and so on...
I use mysql. It has startdate end enddate fields.
thank you in advance.
I can get how many weeks in those giving 2 dates and display them using a
datediff('ww', '2010-12-01', '2010-12-19', false); I found on the internet.
And I can display dates between two dates as follows. But I am having trouble grouping them by week.
$sdate = "2010-12-01";
$edate = "2010-12-19";
$days = getDaysInBetween($sdate, $edate);
foreach ($days as $val)
{
echo $val;
}
function getDaysInBetween($start, $end) {
// Vars
$day = 86400; // Day in seconds
$format = 'Y-m-d'; // Output format (see PHP date funciton)
$sTime = strtotime($start); // Start as time
$eTime = strtotime($end); // End as time
$numDays = round(($eTime - $sTime) / $day) + 1;
$days = array();
// Get days
for ($d = 0; $d < $numDays; $d++) {
$days[] = date($format, ($sTime + ($d * $day)));
}
// Return days
return $days;
}
New answer.
$current_date = strtotime('2010-12-01');
$end_date = strtotime('2010-12-19');
$day_count = 0;
$current_week = null;
do {
if ((int)($day_count / 7) + 1 != $current_week) {
$current_week = (int)($day_count / 7) + 1;
echo 'week-'.$current_week.'<br />';
}
echo date('Y-m-d', $current_date).'<br />';
$current_date = strtotime('+1 day', $current_date);
$day_count ++;
} while ($current_date <= $end_date);
You will definitely need this: Simplest way to increment a date in PHP?. Write a forloop and increment the day every time. You will also need the DateTime class and functions as date. Indeed asking for date('W', yourDateHere) is a nice idea.
You will get something like this (pseudocode)
$startDate;
$endDate;
$nrOfDays = dateDiffInDays($endDate, $startDate);
$currentWeek = date('W',$startDate);
for($i = 0; $i < $nrOfDays; $i++)
{
$newDay = date('+$i day', $startDate); // get the incremented day
$newWeek = date('W', $newDay); // get the week of the new day
if($newWeek != $currentWeek) // check if we must print the new week, or if we are still in the current
print $newWeek;
print $newDay; // print the day
}
Hope this helps. Good luck.
Tools sufficient to do the job:
strtotime('2010-11-23') - to get a timestamp from a date
strtotime('+1 day', $someTimestamp) - to get the next day
date('W', $someTimestamp) - to get the week number (if you want to group by ISO week number)
array_chunk($orderedListOfSuccessiveDates, 7) - to split in groups of seven days (if you don't want to group by ISO week number)
Warning: Never, ever increment days by adding 86400 to the timestamp! That is the easiest way to break everything when Daylight Saving comes along. Either use the strtotime function or the DateTime class.
Here you go. Although this is with weeks starting on sundays (just change it to monday if need be). And it doesnt work if the dates arent in the same year. But it should be pretty easy to fix that. If not_same_year then ...
$start_date = mktime(0, 0, 0, 12, 01, 2010);
$start_date_week_number = (int) date("W", $start_date);
$end_date = mktime(0, 0, 0, 12, 19, 2010);
$end_date_week_number = (int) date("W", $end_date);
$n = $start_date_week_number;
$w = 1;
$date = $start_date;
while($n <= $end_date_week_number) {
echo("<strong>Week " . $w . "</strong><br />");
$s = 0;
$e = 6;
if($n == $start_date_week_number) $s = (int) date("w", $start_date);
elseif($n == $end_date_week_number) $e = (int) date("w", $end_date);
while($s <= $e) {
echo(date("j-m-y", $date) . "<br />");
$c_date = getdate($date);
$date = mktime($c_date['hours'], $c_date['minutes'], $c_date['seconds'], $c_date['mon'], $c_date['mday'] + 1, $c_date['year']);
$s++;
}
$n++; $w++;
}
DEMO HERE
Edit: just fixed it when I realized you wanted to count the weeks (not get the actual week number)...
$startDate = new DateTime('2010-01-01');
$endDate = new DateTime('2010-01-14');
$weeksDays = getWeeksDaysBetween($startDate, $endDate);
foreach($weeksDays as $week => $days)
{
echo "Week $week<ul>";
foreach($days as $day){
echo "<li>$day</li>";
}
echo "</ul>";
}
function getWeeksDaysBetween($startDate, $endDate)
{
$weeksDays = array();
$dateDiff = $endDate->diff($startDate);
$fullDays = $dateDiff->d;
$numWeeks = floor($fullDays / 7) + 1;
$weeksDays[1][] = $startDate->format('Y-m-d');
for ($i = 1; $i <= $fullDays; $i++)
{
$weekNum = floor($i / 7) + 1;
$dateInterval = DateInterval::createFromDateString("1 day");
$weeksDays[$weekNum][] = $startDate->add($dateInterval)->format('Y-m-d');
}
return $weeksDays;
}

Categories