I'm a new to PHP and don't know if my request is possible:
I'd need to get an array with the days of the current week and also indicate for each day if it's the first, second, third, fourth or fifth occurrence of that date for the month.
Examples
For the 1st week of August 2016, it would be:
monday1
tuesday1
wednesday1
thursday1
friday1
saturday1
sunday1
But for the last week of August 2016 (which begins in August and ends in September) it would be:
monday5
tuesday5
wednesday1
thursday1
friday1
saturday1
sunday1
I tried this, but it only works for the current day.
$week_of_the_month = ceil(date('d', $time)/7);
$jd = cal_to_jd(CAL_GREGORIAN,date("m"),date("d"),date("Y"));
echo jddayofweek($jd,1).$week_of_the_month;
$d = new DateTime();
$days = [];
for ($i = 0; $i < 7; $i++) {
$date = $d->format('j');
$days[$date] = $d->format('l - ') . ceil($date/7);
$d->add(new DateInterval('P1D'));
}
That will work for the current date, but you can test it on weeks that cross over two months by setting a specific date to work with:
$d = new DateTime('2016-08-31');
The result is as follows:
print_r($days);
Array
(
[31] => Wednesday - 5
[1] => Thursday - 1
[2] => Friday - 1
[3] => Saturday - 1
[4] => Sunday - 1
[5] => Monday - 1
[6] => Tuesday - 1
)
If you want the dates to always start on the Monday of the current week, the DateTime constructor allows you to pass in a string as such:
$d = new DateTime('monday this week');
Today is Thursday, but it gives:
Array
(
[1] => Monday - 1
[2] => Tuesday - 1
[3] => Wednesday - 1
[4] => Thursday - 1
[5] => Friday - 1
[6] => Saturday - 1
[7] => Sunday - 1
)
Changing Language
If you want to change the language of the date output, that is a separate topic (see here). You will need to have the locales/extensions installed on your system. If you don't want to go down that route, you could just map the days into your language yourself:
$intlDays = [
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'Dimanche'
];
$d = new DateTime('monday this week');
$days = [];
for ($i = 0; $i < 7; $i++) {
$date = $d->format('j');
$output = $d->format('l - ') . ceil($date/7);
$output = str_replace(array_keys($intlDays), $intlDays, $output);
$days[$date] = $output;
$d->add(new DateInterval('P1D'));
}
Related
I have a start_date of 1/10/2018, and an end_date of 1/8/2020, the difference between the two dates in months is 22, that is 1 year 10 months, now, I want to create tables that terminate at the end of each year as follows:
table 1
column_heading will be "1/10/2018 - 31/12/2018"
and the row will be "2 months"
table 2
column_heading will be "1/1/2019 - 31/12/2019"
and the row will be "12 months"
table 3
column_heading will be "1/1/2020 - 1/8/2020"
and the row will be "8 months"
I would like to loop something, maybe the difference between the dates to create the number of tables necessary, if the two dates exist within the same year it will only create 1 table, or 2 if it enters the next year, I am using laravel and carbon to manipulate the dates.
Thank you in anticipation of your help.
Something like this
Here's one way. Note that I had to convert the format of your dates to YYYY-mm-dd in order to use PHP date functions. In the end you'll get an array and it's easy for you to transform the final dates into the format you desire. You can test it here: https://www.tehplayground.com/lvuTdWl91TeItEQC
The code:
<?php
// example code
$s = "1/10/2018";
$e = "1/08/2020";
// reassemble so we can use the date functions YYYY-mm-dd
$s = implode("-", array_reverse(explode("/", $s)) );
$e = implode("-", array_reverse(explode("/", $e)) );
// get the parts separated
$start = explode("-",$s);
$end = explode("-",$e) ;
$iterations = ((intVal($end[0]) - intVal($start[0])) * 12) - (intVal($start[1]) - intVal($end[1])) ;
$sets=[$start[0] => array("start" => $s, "end" => "", "months" => 0)];
$curdstart= $curd = $s;
$curyear = date("Y", strtotime($s));
for($x=1; $x<=$iterations; $x++) {
$curdend = date("Y-m-d", strtotime($curd . " +{$x} months"));
$curyear = date("Y", strtotime($curdend));
if (!isset($sets[$curyear])) {
$sets[$curyear]= array("start" => $curdend, "end" => "", "months" => 0);
}
$sets[$curyear]['months']++;
$sets[$curyear]['end'] = date("Y-m-", strtotime($curdend)) . "31";
}
die(print_r($sets,1));
$mctr = 0 ;
The output:
Array
(
[2018] => Array
(
[start] => 2018-10-1
[end] => 2018-12-31
[months] => 2
)
[2019] => Array
(
[start] => 2019-01-01
[end] => 2019-12-31
[months] => 12
)
[2020] => Array
(
[start] => 2020-01-01
[end] => 2020-08-31
[months] => 8
)
)
Please see my PHP code
$data= '<select>';
for($y = 1; $y <= 52; $y++) {
$numweek = date("W",strtotime('+ '.$y.' weeks', mktime(0,0,0,1,1,$year,-1))); // display 1 to 52
$namemonth = date("F",strtotime('+ '.$y.' weeks', mktime(0,0,0,1,1,$year,-1))); // display january to december
$data .= '<optgroup label="'.$namemonth.'">\n';
for($x = 1; $x <= 52; $x++) {
$data.= '<option value="'.$x.'"'.($x != $week ? '' : ' selected="selected"').'>Week '.$x.'</option>';
}
$data.= '</optgroup>';
}
$data.= '</select>';
I want to display:
January
Week 1
Week 2
Week 3
Week 4
February
Week 5
Week 6
Week 7
Week 8
.......
December
...
Week 52
Here,I just mention weeknumber for two month. If you want to get for all the month then you can modify $inputArray Array.
$inputArray = ["1(Jan)","2(feb)"];
$weekRange = [];
foreach ($inputArray as $val) {
// parse the input string to extract the month
list(, $month) = sscanf($val, '%d(%[^)]s)');
// Get timestamp for the 1st day of the requested month (using current year)
$startMonth = strtotime('1-' . $month);
// Get the ISO week number for the 1st day of the requested month
$startWeek = date('W', $startMonth);
// Get timestamp for the last day of the requested month (using current year)
$endMonth = strtotime('+1 Month -1 Day', $startMonth);
// Get the ISO week number for the last day of the requested month
$endWeek = date('W', $endMonth);
// get a range of weeks from the start week to the end week
if ($startWeek > $endWeek) {
// start week for january in previous year
$weekRange[$val] = range(1, $endWeek);
array_unshift($weekRange, intval($startWeek));
} else {
$weekRange[$val] = range($startWeek, $endWeek);
}
}
echo "<pre>";
print_r($weekRange);
exit;
OUTPUT
Array
(
[1(Jan)] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
[2(feb)] => Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 8
[4] => 9
)
)
I have fetched a current month from my DB which is basically a join date of the user. Lets say the use joined this month and it is May. The code I do to fetch the month name is like this:
$months = array();
array_push($months,date("F",strtotime($me['joinTime'])));
In this case I add the start month to the array, which in this case is May... Now what I'd like to do is as the months go by, I'd like to add each new month to the array.. So for instance in a few days its June, and when June kicks in, I'll add that Month as well to the array.. So my question here is, how can I get the rest of the month names from the start date (May).
I need June, July, August, September, October, November, December...
If the start month was April I'd add May into the array as well...
Can someone help me out with this ?
First you need to get he month number and than you need to use a loop through to end of the year that is 12. For each month number you also need the month name so use DateTime createFromFormat.
Online Check
$months = array();
$num = date("n",strtotime($me['joinTime']));
array_push($months, date("F", strtotime('2016-05-17 16:41:51')));
for($i = ($num + 1); $i <= 12; $i++){
$dateObj = DateTime::createFromFormat('!m', $i);
array_push($months, $dateObj->format('F'));
}
print_r($months); // Array ( [0] => May [1] => June [2] => July [3] => August [4] => September [5] => October [6] => November [7] => December )
Yo can also put it like
$array = array();
array_push($array, date('F')) ;
for ($i=1; $i<= 12 - date('m'); $i++ ){
array_push($array, date('F', strtotime("+$i months"))) ;
}
print "<pre>";print_r($array);
Here we will be using DatePeriod which allows iteration over a set of dates and times, recurring at regular intervals, over a given period.
So we got the end date and we have the start date and then calculated the interval. And then looping over the period we got the array of months.
// current date : 20 Feb 2019
$startDate = new \DateTime('first day of next month');
$endDate = new \DateTime('1st january next year');
$interval = new \DateInterval('P1M');
$period = new \DatePeriod($startDate, $interval, $endDate);
// Start array with current date
$dates = [];
// Add all remaining dates to array
foreach ($period as $date) {
array_push($dates, $date->Format('F'));
}
// output
print_r($dates); die;
Array ( [0] => March [1] => April [2] => May [3] => June [4] => July [5] => August [6] => September [7] => October [8] => November [9] => December )
I have an array of years, months and weeks.
//Returns an array containing the years, months and week numbers between two dates
function year_month($start_date, $end_date)
{
$begin = new DateTime( $start_date );
$end = new DateTime( $end_date);
$end->add(new DateInterval('P1W')); //Add 1 week to include the end date as a week
$interval = new DateInterval('P1W'); //Add 1 week
$period = new DatePeriod($begin, $interval, $end);
$aResult = array();
foreach ( $period as $dt )
{
$aResult[$dt->format('Y')][$dt->format('M')][] = "W".$dt->format('W');
}
return $aResult;
}
echo '<pre>';
print_r(year_month("25-11-2013","26-01-2014"));
echo '</pre>';
it outputs the following:
Array
(
[2013] => Array
(
[Nov] => Array
(
[0] => W48
)
[Dec] => Array
(
[0] => W49
[1] => W50
[2] => W51
[3] => W52
[4] => W01
)
)
[2014] => Array
(
[Jan] => Array
(
[0] => W02
[1] => W03
[2] => W04
[3] => W05
)
)
)
Notice that w01 is in the Dec array instead of the January array. I assume this is because Monday is the start of each week and in this case Monday is the 30th of December. Any ideas on how to get around this? In fact I am not sure what to do with border cases in general. If a week starts in one month but ends in another it should not be inserted into both months I would rather it be in the month in which it ends. But not sure how to go about this.
Use the thursday in the week of the starting date as the starting point, before adding weeks. The thursday will always be in the correct month (since that's what we use to decide if we're going to have week 53 or week 1 in the last week of December). If that thursday is in January, you're going to get W1 and January, if it's in December, you're going to get W53 and December.
If you want the month the week ends each time, use the sunday as the starting point instead.
You assume right, week "belongs" to month in which week start date is, so your output is correct.
If you wish to set month to last day in week, this can be accomplished with setISODate() method:
foreach ($period as $dt) {
$dt->setISODate($dt->format('o'), $dt->format('W'), 7);
$aResult[$dt->format('Y')][$dt->format('M')][] = "W".$dt->format('W');
}
But this will now work for every week that has dates in 2 different months, W05 is now in February.
Demo
$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.