How can I create a function that can return accurate start and end date within date range of given date that separate by week.
For example, a date range is given,
$startDate = '2022-08-05';
$endDate = '2022-08-16';
(2022-08-01 is the first day of the week but I want the data return start from the date that user given so do the end date)
So the output should be like this:
2022-08-05 to 2022-08-07
2022-08-08 to 2022-08-14
2022-08-15 to 2022-08-16
data
data
data
My problem is function I found cannot get data start from that date that user given but start from the first day of week and I have no idea how to modify it or create a new function. Any help is appreciate.
function rangeWeek ($datestr) {
date_default_timezone_set (date_default_timezone_get());
$dt = strtotime ($datestr);
return array (
"start" => date ('N', $dt) == 1 ? date ('Y-m-d', $dt) : date ('Y-m-d', strtotime ('last monday', $dt)),
"end" => date('N', $dt) == 7 ? date ('Y-m-d', $dt) : date ('Y-m-d', strtotime ('next sunday', $dt))
);
}
If I set the start date to '2022-08-05' then the output will be start from the first day of the week, how to let it start from '2022-08-05'?
print_r (rangeWeek('2022-08-05'));//output = Array ( [start] => 2022-08-01 [end] => 2022-08-07 )
You can iterate from start to end date and check the week for each day. So you know the week begin and end.
Example
function rangeWeek(string $start, string $end): array
{
$start = new DateTime($start);
$end = new DateTime($end);
$interval = new DateInterval('P1D');
$period = new DatePeriod($start, $interval, $end);
$weeks = [];
$oldWeek = null;
$weekStart = null;
foreach ($period as $date) {
$week = $date->format('W');
if ($week !== $oldWeek) {
if (null === $weekStart) {
$oldWeek = $week;
$weekStart = $date->format('Y-m-d');
} else {
$weeks[] = ['start' => $weekStart, 'end' => $date->format('Y-m-d'), 'week' => $week];
$weekStart = null;
}
continue;
}
}
$weeks[] = ['start' => $weekStart, 'end' => $end->format('Y-m-d'), 'week' => $week];
return $weeks;
}
$startDate = '2022-08-05';
$endDate = '2022-08-20';
$weeks = rangeWeek($startDate, $endDate);
print_r($weeks);
Output
Array
(
[0] => Array
(
[start] => 2022-08-05
[end] => 2022-08-08
[week] => 32
)
[1] => Array
(
[start] => 2022-08-09
[end] => 2022-08-15
[week] => 33
)
[2] => Array
(
[start] => 2022-08-16
[end] => 2022-08-20
[week] => 33
)
)
Related
Summary: I need to get the year number, the week number and the dates from the given week/year (monday to friday) from the current week, the next week and from the next two weeks.
Problem: I can't get the week number/year correctly in the last weeks in the year
Scenary: I save in the database the year and the week number, following the ISO 8601 rules. This works like an user agenda and the user save its activities of the current week, of the next week and of the next 2 weeks.
What I tried:
I'm generating and array of a given year and date, like this:
Array
(
[week_info] => Array
(
[type] => current_week
[week] => 51
[year] => 2020
[days] => Array
(
[monday] => 2020-12-14
[tuesday] => 2020-12-15
[wednesday] => 2020-12-16
[thursday] => 2020-12-17
[friday] => 2020-12-18
)
)
)
The problem always is happening in the last week's year, getting info like this:
Array
(
[week_info] => Array
(
[type] => next_two_weeks
[days] => Array
(
[monday] => 2022-01-03
[tuesday] => 2022-01-04
[wednesday] => 2022-01-05
[thursday] => 2022-01-06
[friday] => 2022-01-07
)
[year] => 2022
[week] => 01
)
)
How I tried it:
For the current week:
$week = date('W', strtotime('+0 week'));
$year = date('Y', strtotime('+0 week +2 days'));
return array("year" => $year,"week" => $week);
For the next week:
$week = date('W', strtotime('+1 week'));
$year = date('Y', strtotime('+1 week +2 days'));
return array("year" => $year,"week" => $week);
For the next 2 weeks:
$week = date('W', strtotime('+2 weeks'));
$year = date('Y', strtotime('+2 weeks +2 days'));
return array("year" => $year,"week" => $week);
When I get the year and the week number, I get the date set using the following function:
Function receiving $param_year and $param_week as paramaters.
$dates_day = array();
for($day=1; $day<=5; $day++) {
array_push($dates_day, date('Y-m-d', strtotime($param_year."W".$param_week.$day)));
}
$dateset= array(
"week_info" => array(
"type" => $param_week_type,
"days" => array(
"monday" => $dates_day[0],
"tuesday" => $dates_day[1],
"wednesday" => $dates_day[2],
"thursday" => $dates_day[3],
"friday" => $dates_day[4]),
"year" => date("Y", strtotime($dates_day[4])),
"week" => date("W", strtotime($dates_day[0])),
));
return $dateset;
What am I doing wrong? How should I do it correctly?
function test($year, $week) {
$pointInTime = strtotime($year . 'W' . $week);
for ($n = 0; $n != 5; $n++) {
echo("\n" . date('Y-m-d l', $pointInTime));
$pointInTime = strtotime('+1 day', $pointInTime);
};
}
var_dump(test(2020, 53));
// 2020-12-28 Monday
// 2020-12-29 Tuesday
// 2020-12-30 Wednesday
// 2020-12-31 Thursday
// 2021-01-01 Friday
If you want to add the next two weeks:
function test($year, $week, $addWeeks = 0) {
$pointInTime = strtotime($year . 'W' . $week);
if ($addWeeks)
$pointInTime = strtotime('+'.$addWeeks.' weeks', $pointInTime);
for ($n = 0; $n != 5; $n++) {
echo("\n" . date('Y-m-d l', $pointInTime));
$pointInTime = strtotime('+1 day', $pointInTime);
};
}
echo "\n This week: ";
$this->test(2020, 53);
echo "\n Next week: ";
$this->test(2020, 53, 1);
echo "\n Next another week: ";
$this->test(2020, 53, 2);
I want to store names of the week days in an array from given date range.
Eg. If given date range is from 2016-12-1 to 2017-02-22 then i want to store all weekdays comes in this date range.
$timestamp = strtotime('next Sunday');
$days = array();
for ($i = 0; $i < 7; $i++) {
$days[] = strftime('%A', $timestamp);
$timestamp = strtotime('+1 day', $timestamp);
}
Try this. Provide Start date,end date, weekdays as input params
function progDateRange($date, $end_date, array $wkDays, array $excluded)
{
$dates = array();
$current_date = strtotime($date);
$max_date = min(strtotime('+2 years'), strtotime($end_date));
$dow = array_keys($wkDays);
while ($current_date < $max_date) {
if ($excluded && in_array($date_formatted, $excluded, true)) {
continue;
}
if (in_array(date('l'), $dow, true)) {
array_push($dates, $date);
}
$current_date = strtotime('+1 day', $current_date);
$date = date('Y-m-d', $current_date);
}
return $dates;
}
The solution using date and strtotime functions:
$date_from = '2016-12-1';
$date_to = '2017-02-22';
$current = strtotime($date_from);
$max_time = strtotime($date_to);
$weekdays = [];
while ($current <= $max_time) {
// getting weekday name for current timestamp within date range
$weekdays[] = date('l', $current);
$current = strtotime('+1 day', $current); // setting timestamp for each next next day in increase order
}
print_r($weekdays);
The output will be like below:
Array
(
[0] => Thursday
[1] => Friday
[2] => Saturday
[3] => Sunday
[4] => Monday
[5] => Tuesday
[6] => Wednesday
[7] => Thursday
[8] => Friday
[9] => Saturday
[10] => Sunday
[11] => Monday
[12] => Tuesday
[13] => Wednesday
[14] => Thursday
....
...
so my problem is rather simple but the solution keeps evading me. i am trying to get a list of future dates at a set interval that respects week nr in month and day nr in week. for example i need to make a list of dates of the 2nd mondays at 3 months apart.
i have a form where user specifies 2 dates and the interval.
so what i have is something like:
$start_date = "2015-01-07";
$end_date = "2016-01-07";
$period = "+1 month";
then, using this function from this link stackoverflow i get what weeknr my start_date is: (ie: "first monday")
function literalDate($timestamp) {
$timestamp = is_numeric($timestamp) ? $timestamp : strtotime($timestamp);
$weekday = date('l', $timestamp);
$month = date('M', $timestamp);
$ord = 1;
while(date('M', ($timestamp = strtotime('-1 week', $timestamp))) == $month) {
$ord++;
}
$lit = array(null, 'first', 'second', 'third', 'fourth', 'fifth');
return $lit[$ord].' '.$weekday;
}
$day_number = literalDate($start_date);
$list=array();
then. i'm trying to do this
while(strtotime($start_date) <= strtotime($end_date))
{
$list[]=$start_date;
$start_date=date('Y-m-d', strtotime("$start_date $period"));
$month = date('F', strtotime($start_date));
$start_date = date('Y-m-d', strtotime($day_number.' of '.$month)); //this always returns 1970-01-01
}
print_r($list);
as asked in comment my expected output is something like
array(
[0] => 2015-01-07
[1] => 2015-02-04
[2] => 2015-03-04
[3] => 2015-04-01
[4] => 2015-05-06
[5] => 2015-06-03
[6] => 2015-07-01
[7] => 2015-08-05
[8] => 2015-09-02
[9] => 2015-10-07
[10] => 2015-11-04
[11] => 2015-12-02
)
From what I understand, DateInterval should get you what you need:
$start = new DateTime('2015-01-07');
$start->modify('first day of this month');
$end = new DateTime('2016-01-07');
$end->modify('first day of this month');
$interval = DateInterval::createFromDateString('first wednesday');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
$d = $dt->format("d");
if($d <= 7){
echo $dt->format("Y-m-d") . "\n";
}
}
will display:
2015-01-07
2015-02-04
2015-03-04
2015-04-01
2015-05-06
2015-06-03
2015-07-01
2015-08-05
2015-09-02
2015-10-07
2015-11-04
2015-12-02
2016-01-06
strtotime() which works in reference of today.
strtotime("+x days");
strtotime
if you need something in relation to another date...
date("Y-m-d", strtotime($yourdate) + 86400 * $days);
I am tring to get the week from the month having starting Monday and end with Sunday with in same month.
i'll provide month and year.
for example:
$month = '03';
$year = '2014';
then function should return
2014-03-03 to 2014-03-09 as start date of month coz the month has its first Monday on 3rd.
then continue to month till last week.
In march, 2014, 31st starts on Monday but don't finish in march, it finishes at 06-04-2014 so this should not be included in counting.
Now, when i pass month as '04' than the month should count 31st march in its first week.
I hope i make my self clear, sorry for language.
I have tried so far:
$month = "04";
$year = "2014";
$beg = (int)date('W', strtotime("first day of $year-$month"));
$end = (int)date('W', strtotime("last day of $year-$month"));
$weeks = range($beg, $end);
foreach($weeks as $week) {
$result = $this->getStartAndEndDate($week, $year);
print_r($result);
}
function getStartAndEndDate($week, $year)
{
$time = strtotime("1 January $year", time());
$day = date('w', $time);
$time += ((7*$week)+1-$day)*24*3600;
$return[0] = date('Y-m-d', $time);
$time += 6*24*3600;
$return[1] = date('Y-m-d', $time);
return $return;
}
OUTPUT:
Array
(
[0] => 2014-03-03
[1] => 2014-03-09
)
Array
(
[0] => 2014-03-10
[1] => 2014-03-16
)
Array
(
[0] => 2014-03-17
[1] => 2014-03-23
)
Array
(
[0] => 2014-03-24
[1] => 2014-03-30
)
Array
(
[0] => 2014-03-31
[1] => 2014-04-06
)
Array
(
[0] => 2014-04-07
[1] => 2014-04-13
)
You can use the DateTime class for this:
$dt = new DateTime('1st march');
// is this a monday?
if($dt->format('N') !== '1') {
// if not, went to next monday
$dt->modify('next monday');
}
echo $dt->format('Y-m-d')
. ' to ' . $dt->modify('next sunday')->format('Y-m-d');
Output:
2014-03-03 to 2014-03-09
<?php
function get_weeks($month, $year) {
$weeks = array();
$date = DateTime::createFromFormat('mY', $month.$year);
$date->modify('first Monday of this month');
$end = clone $date;
$end->modify('last Monday of this month');
$interval = DateInterval::createFromDateString('1 week');
$period = new DatePeriod($date, $interval, $end);
$counter = 1;
foreach ($period as $dt) {
$end_of_week = clone $dt;
$end_of_week->modify('next Sunday');
$weeks[] = sprintf("Week %u: %s - %s",
$counter,
$dt->format('Y-m-d'),
$end_of_week->format('Y-m-d')
);
$counter++;
}
return $weeks;
}
$weeks = get_weeks('03', '2014');
print_r($weeks);
Array
(
[0] => Week 1: 2014-03-03 - 2014-03-09
[1] => Week 2: 2014-03-10 - 2014-03-16
[2] => Week 3: 2014-03-17 - 2014-03-23
[3] => Week 4: 2014-03-24 - 2014-03-30
)
See it in action
$start_date = "2013-05-01";
$last_date = "2013-08-30";
How can I get dates of tuesdays and thursdays between these two dates?
<?php
$start = new DateTime('2013-05-01');
$end = new DateTime('2013-08-30');
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
if ($dt->format("N") == 2 || $dt->format("N") == 4) {
echo $dt->format("l Y-m-d") . "<br>\n";
}
}
See it in action
What this code does:
Creates a starting date object using DateTime.
Creates a starting date object using DateTime.
Creates a DateInterval object to represent our interval of time to iterate through. In this case 1 day.
Creates a DatePeriod object to manage these objects.
Using DatePeriod, it iterates through the date starting with the starting date and ending at the end date. We use DateTime::format() with the N parameter to get the day number of the week. If the day number of the week is 2 (Tuesday) or 4 (Thursday) echo out it's value.
Some PHP-Fu
$start_date = '2013-05-01';
$last_date = '2013-08-30';
$dates = range(strtotime($start_date), strtotime($last_date),86400);
$days = array('tuesday' => array(), 'thursday' => array());
array_map(function($v)use(&$days){
if(date('D', $v) == 'Tue'){
$days['tuesday'][] = date('Y-m-d', $v);
}elseif(date('D', $v) == 'Thu'){
$days['thursday'][] = date('Y-m-d', $v);
}
}, $dates); // Requires PHP 5.3+
print_r($days);
Output
Array
(
[tuesday] => Array
(
[0] => 2013-05-07
[1] => 2013-05-14
[2] => 2013-05-21
[3] => 2013-05-28
[4] => 2013-06-04
[5] => 2013-06-11
[6] => 2013-06-18
[7] => 2013-06-25
[8] => 2013-07-02
[9] => 2013-07-09
[10] => 2013-07-16
[11] => 2013-07-23
[12] => 2013-07-30
[13] => 2013-08-06
[14] => 2013-08-13
[15] => 2013-08-20
[16] => 2013-08-27
)
[thursday] => Array
(
[0] => 2013-05-02
[1] => 2013-05-09
[2] => 2013-05-16
[3] => 2013-05-23
[4] => 2013-05-30
[5] => 2013-06-06
[6] => 2013-06-13
[7] => 2013-06-20
[8] => 2013-06-27
[9] => 2013-07-04
[10] => 2013-07-11
[11] => 2013-07-18
[12] => 2013-07-25
[13] => 2013-08-01
[14] => 2013-08-08
[15] => 2013-08-15
[16] => 2013-08-22
[17] => 2013-08-29
)
)
Online demo
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
while ($start_date <= $last_date) {
$start_date = strtotime('+1 day', $start_date);
if (date('N',$start_date) == 2 || date('N',$start_date) == 4){
echo date('Y-m-d', $start_date).PHP_EOL;
}
}
<?php echo date('Y-m-d', strtotime('next thursday', strtotime($start_date)));
Also for tuesday ofcourse
Please use the following function for your solution,
function daycount($day, $startdate, $lastdate, $counter=0)
{
if($startdate >= $lastdate)
{
return $counter;
}
else
{
return daycount($day, strtotime("next ".$day, $startdate), ++$counter);
}
}
$start_date = "2013-05-01";
$last_date = "2013-08-30";
echo "Tuesday Count - ".daycount("tuesday", strtotime($start_date), strtotime($last_date));
echo "<br/>";
echo "Thursday Count - ".daycount("thursday", strtotime($start_date), strtotime($last_date));
Try with this
$startDate = strtotime($start_date);
$endDate = strtotime($last_date);
while ($startDate < $endDate) {
echo date('Y-m-d', $startDate ). "\n";
// Give the condition to find last Tuesday
$startDate = strtotime( 'next Tuesday', $startDate );
}
With DateTime:
$start_date = "2013-05-01";
$last_date = "2013-08-30";
$start = new DateTime($start_date);
$clone = clone $start;
$start->modify('next thursday');
$thursday=$start->format('Y-m-d');
$clone->modify('next tuesday');
$tuesday=$clone->format('Y-m-d');
echo $thursday; //2013-05-02
echo $tuesday; //2013-05-07
We need to objects because if in interval tuesday is before thursday we will have next tuesday. But you can modify little code to use one object.
With the help of few php date functions this can be solved easily..
<?php
// Create the from and to date
$start_date = strtotime("2013-05-01");
$last_date = strtotime("2013-08-30");
// Get the time interval to get the tue and Thurs days
$no_of_days = ($last_date - $start_date) / 86400; //the diff will be in timestamp hence dividing by timestamp for one day = 86400
$get_tue_thu_days = array();
// Loop upto the $no_of_days
for($i = 0; $i < $no_of_days; $i++) {
$temp = date("D", $start_date);
if($temp == "Tue" || $temp == "Thu") {
$get_tue_thu_days[] = date("D/M/Y", $start_date); //formating date in Thu/May/2013 formate.
}
$start_date += 86400;
}
print_r($get_tue_thu_days);
if you have a reference date which you know is a tuesday/thursday you can find days which are a multiple of 7 days from your reference date, these days will always be the same day of the week.