Right now my program echo an array of dates generated with for loop. What I'm trying to do is echo dates individually.
Initial code
// initialize an array with your first date
$dates = array(strtotime("+11 days", strtotime("2017-09-04")));
for ($i = 1; $i <= 5; $i++) {// loop 5 times to get the next 5 dates
// add 7 days to previous date in the array
$dates[] = strtotime("+7 days", $dates[$i-1]);
}
// echo the results
foreach ($dates as $date) {
echo date("Y-m-d", $date);
echo "<br>";
}
Initial Output
2017-09-15
2017-09-22
2017-09-29
2017-10-06
2017-10-13
What I have tried
echo $dates[0];//print first date
echo "<br>";
echo $dates[1];//print second date
Trial Output
1505426400
1506031200
How can I achieve this?
Either you need to use date() when outputting the elements as well - as they still are timestamps in the array (you don't change anything in the loop, you just print the elements), or you need to change the elements when you loop over them.
Alternative 1: Format on output
Convert from timestamp to datestring on output. This will still have timestamps in the array.
echo date("Y-m-d", $dates[0]);
Alternative 2: Alter the elements in the array
Alternatively, you can alter the value in the array when you loop it through foreach. If you pass by reference, you can change the value of the element inside the loop, by using & (which means that the variable is a reference and not a copy). This means that you now have datestrings in the array, and not timestamps.
foreach ($dates as &$date) {
echo $date = date("Y-m-d", $date);
echo "<br>";
}
If you pass by reference, you can now print it directly, as it will no longer contain the timestamp, since we changed it to the datestring.
echo $dates[0];
You should only adapt one of the alternatives, whichever is most suitable for your application.
PHP.net "Passing by Reference"
try this
echo date("Y-m-d", ($dates[0])) . '<br>';
echo date("Y-m-d", ($dates[1])) . '<br>';
Related
I have an array of PHP DateTime objects:
$dates = [
new DateTime('2019-08-15'),
new DateTime('2019-08-19'),
new DateTime('2019-08-20')
];
What I would like to receive from this array is the average date, which in my calculation would be 2019-08-18.
Is there a simple way of doing this without breaking down the date parts for each item and finding the average of all of them and then splicing it back together?
Thank you!
Basically you have no choice other than to iterate over all the values and summing them (using timestamps is the most efficient way), taking the average and then converting that value back to a date:
echo date('Y-m-d', array_reduce($dates, function ($c, $d) {
return $c + $d->format('U');
}, 0) / count($dates));
An alternate way would be to find the difference between each of the dates and the first date in the array, and then take the average of those values and add it to the first date:
$days = 0;
foreach ($dates as $date) {
$days += $dates[0]->diff($date)->days;
}
$days = intdiv($days, count($dates));
$avg_date = (clone $dates[0])->modify("+$days days");
echo $avg_date->format('Y-m-d');
In both cases the output is:
2019-08-18
Demo on 3v4l.org
I'm trying to make a function that formats dates from nested arrays lying in the same array. I'm able to locate and echo the values in the array, however I'm struggling to format the date into the way I want to print it out. The way my code is set up I have one function that goes into the array, iterates over each of the nested arrays and prints out the value attached to the key that it is set to look for.
That works fine, but my other function is meant to take the date and format it into the way I wish it to print out with the date function and just no go. I've got a few ideas as to why this is the case, but I know I don't know which is why I'm hoping someone can help. Thanks in advance, I appreciate anyone trying to help me on this. I'm new to php so it's been an interesting foray.
I've used the php date, strtotime, and date_create_from_format functions to attempt to take the date and format it into a date the way I want to.
// Example clip from array
$Full_List_Of_Recover_Items = array (
0 =>
array (
'ActionTimeStamp' => '2018-07-23 15:17:23'
)
);
// End format would look like July 23, 2018 3:17pm
<?php
function valGet($arr, $value)
{
foreach($arr as $row)
{
foreach($row as $key => $val)
{
if ($key == $value)
{
if ($val == NULL)
echo "empty";
else
echo $val;
}
}
}
}
function timeFormat($timeStamp)
{
// split the array value to set up date
$first = explode(" ", $timestamp);
$second = explode("-", $first);
$third = explode(":", $second);
// format the date and convert it attempt
$stringTime = strtotime("D, F, d, Y, g, i", $timestamp);
$date = date_create_from_format("Y-m-d H:i:s");
echo date($date($stringTime));
}
?>
// invocation on html
<p>
<?php
echo timeFormat(valGet($Full_List_Of_Recover_Items, 'ActionTimeStamp'));
?>
</p>
You need to modify your timeFormat function. Just use strtotime:
$timeStamp = '2018-07-23 15:17:23';
echo date("F j, Y, g:i a", strtotime($timeStamp)); // prints July 23, 2018, 3:17 pm
And here you can see the documentation for all kind of format: PHP manual date
Reference: strtotime
I have several dates, some of the past, some of the future, and I want to show only the next date in the future of this list. If there is no date in the future, I want to echo some text.
I am using ACF Date Picker inside a Repeater. First of all, I think I have to get the current date, to compare it with the others:
date_default_timezone_set('Europe/Berlin');
$date = date('Ymd', time());
I chose the Ymd format because the repeater outputs the dates the exact same way. Now I need to check somehow all subfields inside my repeater. I guess this is done using somehow like
$rows = get_field('repeater_field_name');
if($rows) {
foreach($rows as $row) {
// compare the dates, choose only the next coming date
// dates are stored in the_sub_field('repeater_date_field');
}
}
How can I get all the_sub_field('repeater_date_field') of my get_field('repeater_field_name') values? And how can I detect its row (for adding other sub fields to the same row)?
You can store your all dates in array. Then sort it in ascending order. Then take the first date from the list which is greater than today.
Please look into below code.
date_default_timezone_set('Europe/Berlin');
$date = date('Ymd', time());
$dates = array();
$rows = get_field('repeater_field_name');
if($rows) {
foreach($rows as $row) {
$dates[] = $row->date_field;
// compare the dates, choose only the next coming date
// dates are stored in the_sub_field('repeater_date_field');
}
}
sort($dates);
$final_date = "";
foreach($dates as $date_row){
if($date_row > $date){
$final_date = $date_row;
return true;
}
}
echo $final_date;
You can compare 2 date to solve this problem. For example
$date_bef = strtotime("151218"); // December 18, 2015
$date_after = strtotime("151219"); // December 19, 2015
if($date_after - $date_bef == 1)
echo "This is a next day";
If you don't want compare, you can add 1 day to existing time, example
$next_day = date("Ymd",strtotime("151220") + 60*60*24);
I've created an If an Else Statement but it doesn't work properly.
I have some dates within my SQL which have been retrieved and stored in variables using PHP.
I'm comparing the current date with the dates from the database but for some reason, it thinks for example that 29-09-2015 if LESS THAN 31-01-2015.
I can understand that the format could be the issue d,m,Y but I thought I'd corrected that already.
Here's the code:
$today = date('d-m-Y');
$date = $row['respondby'];
$euDate= date("d-m-Y", strtotime($date));
<?php
if($today < $euDate){ echo "<td>". $today." is less than ". $euDate ."</td>";
}
else{
echo"<td>Lost somewhere in between ?!?!?! :S </td>";
}
?>
As a result it prints
29-09-2015 is less than 30-06-2015
today's date was 29-09-2015 and one of the dates was in the data was this one as shown.
Thank you everyone that helps.
Comparison of dates as strings uses lexicographical order, hence your result is "correct".
Instead of d-m-Y format, try to use Y-m-d, this guarantees proper ordering.
$today = date('Y-m-d');
$date = $row['respondby'];
$euDate= date("Y-m-d", strtotime($date));
if($today < $euDate) { [...] }
Or, you can use Date objects instead:
$today = new Date('now');
$euDate= new Date($row['respondby']);
if($today < $euDate) { [...] }
I'm trying to modify a DateTime object in a function passed as an reference:
<?php
$date = new DateTime('2012-02-12');
for($n1 = 0; $n1 < 10; $n1++) {
$date->modify('first day of next month');
setDate($date, 15);
echo $date->format('Y-m-d') . "<br />\n";
}
function setDate(&$date, $day) {
$date->setDate($date->format('Y'), $date->format('m'), $day);
}
?>
But the result is not as expected. Did I got something wrong with this references stuff?
EDIT:
Expected result:
2012-03-15
2012-04-15
...
Result with function above:
2012-03-01
2012-04-01
...
My PHP didn't like the 'first day of nest month' bit, but worked with '+1 month'. Since you are setting the day absolutely I wouldn't worry about it not being on the first. Or if it needs to be you can set it to the first before you go into the loop.
So, this worked for me. I added the new DateTimeZone('America/New_York') so it would stop bugging me about it not being set (shared server.) And removed the pass by reference (&) bit since all objects are passed by reference by default in PHP now.
<?php
$date = new DateTime('2012-02-12',new DateTimeZone('America/New_York'));
for($n1 = 0; $n1 < 10; $n1++) {
$date->modify('+1 month');
setDate($date, 15);
echo $date->format('Y-m-d') . "<br />\n";
}
function setDate($date, $day) {
$date->setDate($date->format('Y'), $date->format('m'), $day);
}
?>
You are already passing a reference to the DateTime object. There is no need to pass an instance of DateTime implicitly as a reference. If you need a copy of the DateTime object, you will need to use clone keyword.
As far as the result, it iterates over 15th of every sequential month, which, reading the code, I expected to be the outcome.