I need to create a date-time with specific day each month between a start date and a end date.
Example :
Specific day : 04
Start : 2016-12-22
End : 2017-03-06
Output needed : 2016-01-04 ; 2016-02-04 ; 2016-03-04
How can I do that?
You can create a DatePeriod object and iterate over it to get all the dates you need:
$start = new DateTime('2016-12-22');
$end = new DateTime('2017-03-06');
// Compute the occurrence on the same month as $start
$first = new DateTime();
$first->setDate($start->format('Y'), $start->format('m'), 4);
// If it is in the past of $start then the first occurrence is on the next month
if ($first < $start) {
$first->add(new DateInterval('P1M'));
}
// Create a DatePeriod object that iterates between $first and $end
// in increments of 1 month
$period = new DatePeriod($first, new DateInterval('P1M'), $end);
// Run through the list, process each item
foreach ($period as $day) {
echo($day->format('Y-m-d')."\n");
}
I found it ! This following code is working for me :
$d1 = new DateTime("2016-12-22");
$d2 = new DateTime("2017-03-06");
$dd = '04';
if ($dd < $d1->format('d') ) {
$d1->add(new \DateInterval('P1M'));
$date = $dd.'-'.$d1->format('m').'-'.$d1->format('Y');
} else {
$date = $d1->format('Y').'-'.$d1->format('m').'-'.$dd;
}
$date = new DateTime($date);
print_r($date);echo('<br />');
while ($date->add(new \DateInterval('P1M')) <= $d2){
$d1->add(new \DateInterval('P1M'));
$date = $dd.'-'.$d1->format('m').'-'.$d1->format('Y');
$date = new DateTime($date);
print_r($date);echo('<br />');
}
Related
My Issue:
I have found a way to select every other Wednesday here: PHP Select every other Wednesday with the following code.
<?php
$number_of_dates = 10;
$start_date = new DateTime("1/1/20");
$interval = DateInterval::createFromDateString("second wednesday");
$period = new DatePeriod($start_date, $interval, $number_of_dates - 1);
foreach ($period as $date) {
$datex = $date->format("m-d-Y").PHP_EOL;
echo "$datex<br>";
}
?>
What I need to do is put every other Wednesday into an array.
I can put a range of dates into an array, but it uses every day in the range with the following code. I just need it to be every other Wednesday. How can I do this?
<?PHP
$dates = array();
$datetime1 = new DateTime("2020-01-01");
$datetime2 = new DateTime("2020-1-31");
$interval = $datetime1->diff($datetime2);
$days = (int) $interval->format('%R%a');
$currentTimestamp = $datetime1->getTimestamp();
$dates[] = date("m/d/Y", $currentTimestamp);
for ($x = 0; $x < $days; $x++)
{
$currentTimestamp = strtotime("+1 day", $currentTimestamp);
$dates[] = date("m/d/Y", $currentTimestamp);
}
print_r($dates);
?>
Try this :
<?php
$dates = array();
$datetime = new DateTime();
for ($i = 0; $i < 52; $i++) {
$datetime->modify('next Wednesday');
array_push($dates, $datetime->format('m/d/Y'));
}
print_r($dates);
What does it do ?
it gets the current time (you can customize this in the new
Datetime),
then loops for 52 times (you can customize this too in the for loop),
then finds the next wednesday using modify.
Live Demo :
http://sandbox.onlinephpfunctions.com/code/57c6a6b682a07f75bc1c507c588c844d84330610
Regards
Your first snippet is already outputting the right set of dates, so you just would need to put each of those in an array, instead of echoing them.
(Although I don't know if it's really necessary to do so, since you can already loop over the $period variable - but it depends exactly what you plan to do with the data afterwards).
Example:
$number_of_dates = 10;
$start_date = new DateTime("1/1/20");
$interval = DateInterval::createFromDateString("second wednesday");
$period = new DatePeriod($start_date, $interval, $number_of_dates - 1);
$dates = array(); //declare a new empty array
foreach ($period as $date) {
$dates[] = $date; //add the date to the next empty array index
}
var_dump($dates);
Or if you actually want an array containing the string representations of those dates, in that specific format, then:
$dates2 = array();
foreach ($period as $date) {
$dates2[] = $date->format("m-d-Y");
}
var_dump($dates2);
Live demo: http://sandbox.onlinephpfunctions.com/code/9e58e552edff204ae6df3ca9b437b8c597edf2b3
Give it a try
<?PHP
$dates = [];
$datetime1 = new DateTime("2020-01-01");
$datetime2 = new DateTime("2020-01-31");
$datetime1->modify('wednesday'); // Start with wednesday
while($datetime1 < $datetime2){
$dates[] = $datetime1->format('Y-m-d');
$datetime1->modify('second wednesday'); // Other Wednesday
}
print_r($dates);
?>
this code get count hours between tow times
ineed out put like this
6:00:00AM
6:30:00AM
7:00:00AM
7:30:00AM
8:00:00AM
8:30:00AM
......
10:30:00PM
how i can do this
$start = date_create('6:00:00AM');
$end = date_create('11:00:00PM');
$diff = date_diff($end, $start);
print_r($diff->h);
Alternatively you could use DatePeriod to build the list of dates on the desired specification, as opposed to iterating over comparisons of the date and adding the increment.
$start = date_create('6:00:00AM');
$end = date_create('11:00:00PM');
$interval = \DateInterval::createFromDateString('30 minutes');
$periods = new \DatePeriod($start, $interval, $end);
foreach ($periods as $date) {
echo $date->format('h:i:sA') . \PHP_EOL;
}
Result: https://3v4l.org/FnEae
06:00:00AM
06:30:00AM
07:00:00AM
07:30:00AM
08:00:00AM
08:30:00AM
//..
10:30:00PM
Since \DateTime::diff() won't always show the total hours between dates with different days, you can count the hours between the two dates by using iterator_count on the DatePeriod of the desired interval:
$start = date_create('6:00:00AM');
$end = date_create('11:00:00PM');
$interval = \DateInterval::createFromDateString('1 hour');
$periods = new \DatePeriod($start, $interval, $end);
echo iterator_count($periods) . ' hours';
Result: https://3v4l.org/P75K7
17 hours
<?php
$start = date_create('6:00:00AM');
$end = date_create('11:00:00PM');
$halfHour = new DateInterval('PT1800S');
while ($start < $end) {
print ($start->format('h:i:sA').PHP_EOL);
$start->add($halfHour);
}
?>
Create 2 Datetime objects and a date interval object and iterate while less than the end Datetime add the interval each time.
$start = date_create('6:00:00AM');
$end = date_create('11:00:00PM');
$interval = new DateInterval('PT30M');
while ($start <= $end) {
echo $start->format('H:i:s');
$start->add($interval);
}
I have two dates
2016-06-22 , 2016-07-11
I need to print the date in numbers for example,
22,23,24,25,26,27,28,29,30,1,2,.....11
if the month is july to august it should print
22,23,24,25,26,27,28,29,30,31,1,2,.....11
according to month wise also in PHP.
Thank you.
This will work for you .. Look The DatePeriod class
A date period allows iteration over a set of dates and times, recurring at regular intervals, over a given period.
<?php
$begin = new DateTime( '2016-06-22' );
$end = new DateTime( '2016-07-11' );
$end = $end->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date){
echo $date->format("d") . "<br>";
}
?>
LIVE EXAMPLE : CLICK HERE
You have to iterate over date between start and end date and print it in format d.
$fromDate = new DateTime('2016-06-22');
$toDate = new DateTime('2016-07-11');
$days = array();
while($fromDate <= $toDate) {
$days[] = $fromDate->format('d');
$fromDate->modify('tomorrow');
}
echo implode(',', $days);
Try:
function createDateRangeArray($strDateFrom,$strDateTo)
{
// inclusive array of the dates between the from and to dates.
// could test validity of dates here but I'm already doing
// that in the main script
$aryRange=array();
$iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2), substr($strDateFrom,8,2),substr($strDateFrom,0,4));
$iDateTo=mktime(1,0,0,substr($strDateTo,5,2), substr($strDateTo,8,2),substr($strDateTo,0,4));
if ($iDateTo>=$iDateFrom)
{
array_push($aryRange,date('d',$iDateFrom)); // first entry
while ($iDateFrom<$iDateTo)
{
$iDateFrom+=86400; // add 24 hours
array_push($aryRange,date('d',$iDateFrom));
}
}
return $aryRange;
}
$arr = createDateRangeArray("2016-06-22","2016-07-11");
echo implode(",",$arr);
in mysql
select date_format(my_date_column, '%d$) from my_table
in php
$date = new DateTime('2016-06-22');
echo $date->format('d');
echo the day number
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
I need to generate a list of dates (with either php or mysql or both) where i have a start and end date specified? For example if the start date is 2012-03-31 and the end date is 2012-04-05 how can i generate a list like this?
2012-03-31
2012-04-01
2012-04-02
2012-04-03
2012-04-04
2012-04-05
I have a mysql table with a start and end date but i need the full list of dates.
Something like this should do it:
//Get start date and end date from database
$start_time = strtotime($start_date);
$end_time = strtotime($end_date);
$date_list = array($start_date);
$current_time = $start_time;
while($current_time < $end_time) {
//Add one day
$current_time += 86400;
$date_list[] = date('Y-m-d',$current_time);
}
//Finally add end date to list, array contains all dates in order
$date_list[] = $end_date;
Basically, convert the dates to timestamps and add a day on each loop.
Using PHP's DateTime library:
<?php
$start_str = '2012-03-31';
$end_str = '2012-04-05';
$start = new DateTime($start_str);
$end = new DateTime($end_str . ' +1 day'); // note that the end date is excluded from a DatePeriod
foreach (new DatePeriod($start, new DateInterval('P1D'), $end) as $day) {
echo $day->format('Y-m-d'), "\n";
}
Source
Try this:
<?php
// Set the start and current date
$start = $date = '2012-03-31';
// Set the end date
$end = '2012-04-05';
// Set the initial increment value
$i = 0;
// The array to store the dates
$dates = array();
// While the current date is not the end, and while the start is not later than the end, add the next day to the array
while ($date != $end && $start <= $end)
{
$dates[] = $date = date('Y-m-d', strtotime($start . ' + ' . $i++ . ' day'));
}
// Output the list of dates
print_r($dates);