I have a situation whereby a series of 15 dates have been created, currently in UNIX timestamps.
Another variable <?php $dateidate = date(strtotime('+20 days')); ?>
The objective is to find the smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'
Once we've done that is there a way to get the second smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'.
So, you have 15 dates which are UNIX timestamps. Useful.
Ok, here's what you can do to do it easily:
$datearray = array(timestamp1,timestamp2,etc.) // an array of timestamps
$dateidate = time() + 1728000; //current time + 20 days worth of seconds (20 * 24 * 60 * 60)
foreach($datearray as $key => $date)
{
if($date < $dateidate)
{
unset $datearray[$key]; //Remove timestamp from original array if less than $dateidate
}
}
$earliestdate = min($datearray);
//min returns the least of the values in the array, opposite of max, which you could use to find the latest date in the array
$date = date('d-m-Y',$earliestdate);
strtotime generates a timestamp.
instead of this:
<?php $dateidate = date(strtotime('+20 days')); ?>
do this:
<?php $dateidate = strtotime('+20 days'); ?>
Put all timestamps into an array with special keys so you can distinguish which one is your pivot.
Sort that array and do what you need to do with the sorted array.
This solution filters the $dates array which stores the timestamps using an anonymous function, so in the $shorterOnes array you will have all the timestamps that are bigger than $dateidate.
Then the array is sorted, the first one will be smallest and so on.
$dateidate=strtotime('+20 days');
$dates=array(/*timestamps*/);
$shorterOnes=array_filter($dates, function ($v) use ($dateidate) {
return $v>$dateidate;
});
sort($shorterOnes);
echo date('d-m-Y', $shorterOnes[0]);
echo date('d-m-Y', $shorterOnes[1]);
Anonymous functions only work from PHP 5.3. Lower than that, you need to use create_function().
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
How do I work out the average time from an array of times.
I have an array that looks like this :
('17:29:53','16:00:32')
And I wish to achieve the result 16:45:12 using PHP.
date('H:i:s', array_sum(array_map('strtotime', $array)) / count($array))
Untested solution typed on my phone, should work though.
$times = array('17:29:53','16:00:32');
$totaltime = '';
foreach($times as $time){
$timestamp = strtotime($time);
$totaltime += $timestamp;
}
$average_time = ($totaltime/count($times));
echo date('H:i:s',$average_time);
convert both using strtotime() function
add the value
divide by 2 (or how many items there in your array)
convert back to normal time format
Loop over all Entries and add times, converted to seconds
Divide by length of Array and convert back to hh:mm:ss
I have an array with dates as keys and prices as values. Like this:
Array
(
[2016-11-11] => 25.05
[2016-11-12] => 25.05
[2016-11-13] => 25.05
[2016-11-14] => 25.05
...
)
Now i need to calculate the mean value of today - 1 till today - 8. Of course it should also calculating correctly if there is less than 8 entries.
I'm thinking of extracting the keys and filter for the values and put that all in for loop. But i bet there will be a better way. I am at least happy for an idea in which direction to start with. May you help me?
The "today" i defined like this:
date_default_timezone_set("Europe/Berlin");
$timestamp = time();
$today = date("Y-m-d",$timestamp);
edit:
The output should be like
$last_week_mean = "value" of key[today-1] + "value" of key [today-2]
+ ... / count(amount of key values in this range)
But i don't know how to build this query/filter - thing :)
You can use array_filter with ARRAY_FILTER_USE_KEY to get the specific date range you want. But after than, you don't need to use a loop to calculate the average. You can just use sum / count of the filtered array.
$d1 = date('Y-m-d', strtotime('8 days ago'));
$d2 = date('Y-m-d', strtotime('1 day ago'));
$range = array_filter($your_array, function($date_string) use ($d1, $d2) {
return $date_string >= $d1 && $date_string <= $d2;
}, ARRAY_FILTER_USE_KEY);
$average = array_sum($range) / count($range);
Also, just in case you're getting your initial array from a database, it would most likely be easier and more efficient to only select the dates you want to begin with.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get most recent date from an array of dates?
I have a timetable which is an array:
array(
'01.01.2012|11:00',
'01.01.2012|14:30',
'01.01.2012|16:24', // example match
'01.01.2012|17:20',
'01.01.2012|17:43',
'02.01.2012|10:20',
'02.01.2012|12:30',
); // etc.
I want a Cron job that will check current date/time and compare to ones in array. First I check if the date is a match, that's no problem. But then I need to find and display the earliest time from that array which is after the current time. If there's no suitable time within the same date then I display the earliest time from the next date.
For example: lets take the array above and current date/time of 01.01.2012|14:45
The date is a match so we continue
The next time from the array 16:24, but how to find it using PHP? And if the current time is higher than anything for the same date in array, then get the earliest time from next date?
Obviously to get the string with correct date I use "foreach" and "if" and it returns fine. But then how do I go through the times?
Convert to timestamp, sort and iteratively compare with current time.
$ts = array_map(
create_function('$a','return strtotime(str_replace("|", " ", $a));'),
$dates);
$len= count($ts); $now = time();
sort($ts);
for($i=0;$i<$len && (!($now<$ts[$i]));$i++);
echo date("d.m.Y|H:i",$ts[$i]);
Functions of Interest
array_map
create_function
str_replace
If you convert these to UNIX timestamps, you can sort them numerically, loop through and take the first item that is larger than the current timestamp.
You might consider converting those dates to UNIX timestamps:
function getUnixTimestamp($string) {
list($date, $time) = explode('|', $string);
return strtotime("$date $time");
}
Then you could use something like:
$array = array(); // from example
$timestamps = array_map('getUnixTimestamp', $array);
$current = time();
// create an array mapping timestamp to string
$keyedArray = array_combine($timestamps, $array);
// sort by timestamp
ksort($keyedArray);
foreach ($keyedArray as $timestamp => $string) {
if ($timestamp > $current) {
// this is the first timestamp after current time
}
}
You may want to do some extra checking on $timestamp, making sure it's either on the same or next day, but it's easier to work with timestmap comparisons than string matches.
Write a comparison function for the date-time format you have then loop through until you find a date greater or equal to your reference date.
function compareDateTime($dt1, $dt2) {
sscanf($dt1, "%d.%d.%d|%d:%d", $day, $month, $year, $hour, $minute);
$comp1 = $year . $month . $day . $hour . $minute;
sscanf($dt1, "%d.%d.%d|%d:%d", $day, $month, $year, $hour, $minute);
$comp2 = $year . $month . $day . $hour . $minute;
return $comp1 - $comp2;
}
Returns -ve when $dt1 < $dt2 and +ve when $dt1 > $dt2
How do I work out the average time from an array of times.
I have an array that looks like this :
('17:29:53','16:00:32')
And I wish to achieve the result 16:45:12 using PHP.
date('H:i:s', array_sum(array_map('strtotime', $array)) / count($array))
Untested solution typed on my phone, should work though.
$times = array('17:29:53','16:00:32');
$totaltime = '';
foreach($times as $time){
$timestamp = strtotime($time);
$totaltime += $timestamp;
}
$average_time = ($totaltime/count($times));
echo date('H:i:s',$average_time);
convert both using strtotime() function
add the value
divide by 2 (or how many items there in your array)
convert back to normal time format
Loop over all Entries and add times, converted to seconds
Divide by length of Array and convert back to hh:mm:ss