How to take average of times with negative values PHP? - php

I have an array say:
array("10:10:20", "-20:00:10", "14:15:00", "08:10:00");
I tried using strtime but it is giving me error as it cant convert negative values to timestamp. Is there any another way?

After rereading the question I made a little snippet, the average is a sum of numbers. So i'm guessing this should be correct. To bypass the negative timestamps, you just need to calculate the absolute one, make it negative and add it to the sum.
<?php
$timings = array("10:10:20", "-20:00:10", "14:15:00", "08:10:00");
//$timings = array("-10:10:20", "-10:10:20", "-10:10:20", "-10:10:20");
$totalTime = 0;
foreach($timings as $timing) {
$isNegativeTime = strpos($timing, '-') !== false;
$time = strtotime(str_replace('-', '', $timing));
if ($isNegativeTime) $time *= -1;
$totalTime += $time;
}
$avgTiming = $totalTime / count($timings);
$isNegativeAvgTime = $avgTiming < 0;
$avgTiming = date('h:i:s', abs($avgTiming));
echo ($isNegativeAvgTime ? '-':'').$avgTiming;

<?php
$moredownvotes = array("10:10:20", "-20:00:10", "14:15:00", "08:10:00");
$nb_lol = count($moredownvotes);
for ($i = 0; $i < ($nb_lol - 1); ++$i)
{
$pattern = '/^-(.*)/';
$replacement = '${1}';
$moredownvotes[$i] = preg_replace($pattern, $replacement, $moredownvotes[$i]);
}
print "<pre>";
print_r($moredownvotes);
print "</pre>";
?>
Result :
Array
(
[0] => 10:10:20
[1] => 20:00:10
[2] => 14:15:00
[3] => 08:10:00
)
NOW u can use DateTime functions or w/e u want
$date = DateTime::createFromFormat('H:i:s', $moredownvotes[$i]);
echo date_format($date, 'H:i:s');
**RESULT ** : 10:10:20
PHP.net createFromFormat function

Related

How to split a string in desired format in php

I've a string like below
$num = "20142311.235504";
I want to split the string in below format
$date['year'] = 2014;
$date['Month'] = 23;
$date['day'] = 11;
$date['hour'] = 23;
$date['min'] = 55;
$date['sec'] = 04;
or even in date form like below
2014/23/11 23:55:04
I tried using preg_split('/(d{4})/',$num,$matches); and str_split but am not getting the desired output. Your help is highly appreciated.
If the string is a date, you can do this :
$num = "20142311.235504";
// You create a date with your string according to your current format
$date = date_create_from_format("Ydm.His", $num);
// Now you can play with it
$formattedDate = $date->format("Y/d/m H:i:s"); // `string(19) "2014/23/11 23:55:04"`
$dateTest['year'] = $date->format("Y"); // 2014
$dateTest['Month'] = $date->format("m"); // 11
$dateTest['day'] = $date->format("d"); // 23
$dateTest['hour'] = $date->format("H"); // 23
$dateTest['min'] = $date->format("i"); // 55
$dateTest['sec'] = $date->format("s"); // 04
Demo here : http://sandbox.onlinephpfunctions.com/
With the help of regex you can do this. In pattern create capture group for garbing year, months, days, hours, minutes and seconds. Simple example:
$str = "20142311.235504";
preg_match('~^(?<year>\d{4})(?<day>\d{2})(?<month>\d{2}).(?<hour>\d{2})(?<minute>\d{2})(?<second>\d{2})$~', $str, $match);
echo '<pre>', print_r($match);
But I prepare you to use date_create_from_format() which is more easier and faster than regex. First, convert a known date format separated by -, explode that format to convert an array and finally assign the array to a set of key [by array_combine()]. Example:
$str = "20142311.235504";
$match = array_combine(['year', 'month', 'day', 'hour', 'minute', 'second'], explode('-', (date_create_from_format("Ydm.His", $str))->format('Y-m-d-H-i-s')));
echo '<pre>', print_r($match);

compare driving distance from JSON array

I'm using googledistancematrix api for calculating distance from login user to all my fields of db. That's my controller code.
$field_list = Field::all();
for ($i=0; $i < count($field_list); $i++)
{
$destination = $field_list[$i]['latitude'] . "," . $field_list[$i]['longitude'];
$details = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=$origin&destinations=$destination&mode=driving&sensor=false";
$json = file_get_contents($details);
$details = json_decode($json, TRUE);
if (count($details['destination_addresses']) > 0 )
{
$distance = $details['rows'][0]['elements'][0]['duration']['text'];
$field_list[$i]->distance = $distance;
}
}
By this i'm getting following response:
https://jsoneditoronline.org/?id=a35cedef327244ceb19ed35a2a4c8ddf
But i want to show only those fields whose distance < or = 30 mins.
Thanks
It's a simple matter to convert the time to seconds using strtotime() as follows:
$time=strtotime($details['rows'][0]['elements'][0]['duration']['text']);
if (($time-time()>1800) {
// ignore this element, probably in loop so do a continue
}
This is based on using your example line above which is only for a single element. You would need to wrap it with a loop and perform the calculation for each element.
You can use strtotime
$min = strtotime("30 mins");
$val = strtotime("0 hours 10 mins");
echo $min <= $val? "yes":"no";
(here if you want to test it)
in your case
if (count($details['destination_addresses']) > 0 ){
$min = strtotime("30 mins");
$distance = $details['rows'][0]['elements'][0]['duration']['text'];
if($min <= strtotime($distance)){
//do your logic
}
}

Use PHP to change multiple number to another number

In text, i have a lot of time number, then i want to change hour to another timezone (+6), example :
00:15 => 06:15
01:00 => 07:00
... and so on.
I'm trying this :
$result = str_replace(
array("00:","01:","02:","03:","04:","05:","06:","07:","08:","09:","10:","11:","12:","13:","14:","15:","16:","17:","18:","19:","20:","21:","22:","23:"),
array("06:","07:","08:","09:","10:","11:","12:","13:","14:","15:","16:","17:","18:","19:","20:","21:","22:","23:","00:","01:","02:","03:","04:", "05:"),
$text
);
echo $result;
But 18: will replace with 04: because php replace 18: to 22: then continue replace 22: to 04:
How to solved this, thank you.
// Edit : To #user3414969 and #Medda86: $text is the data i'm get from another site, that mean i can not control the source, only way to do is replace
// Edit 2 : Here is content : http://bongdatv.net/test.php
// Edit 3: Please solve this problem with replace way, not calculation number way.
I think best is to use the timestamp format, add the time and get out the new time from that.
http://php.net/manual/en/function.time.php
$time = array("00:","01:","02:","03:","04:","05:","06:","07:","08:","09:","10:","11:","12:","13:","14:","15:","16:","17:","18:","19:","20:","21:","22:","23:");
$required_time = array();
foreach($time as $t){
$hour = $t."00"; // 00 appending 0 minites
$hours_plus = 6; // adding 6 hours
$required_time[] = date('H:', strtotime($hour)+($hours_plus*60*60));
}
echo "<pre>";
print_r($required_time);
echo "</pre>";
Optimal way is as suggested by Medda86
However, you can try upon this way
$array = ("00:","01:",....);
//Then you can loop over array and add the time
for($i=0 ; $i < sizeof($array);$i++){
$array[$i] = intval($array[$i]+6)%24;
if($array[$i] < 10)
$array[$i] = str_pad($array[$i],2,'0',STR_PAD_LEFT).':';
else
$array[$i] .= ':';
}
Try this:
$yourArr = array('00:15','01:00','00:30');
foreach ($yourArr as $key => $value) {
$timestamp = strtotime($value) + 60*60*6; // add hours as per your need.
$time = date('H:i', $timestamp);
$newArr[] = $time;
}
echo "<pre>";
print_r($newArr);
Result is:
Array
(
[0] => 06:15
[1] => 07:00
[2] => 06:30
)

how do I concatenate the string values of two arrays pairwise with PHP?

So I have two arrays
Array
(
[0] => test
[1] => test 1
[2] => test 2
[3] => test 3
)
and
Array
(
[0] => test
[1] => test 1
[2] => test 2
[3] => test 3
)
I want to combine them together so I get an array like this?
Array
(
[0] => test test
[1] => test 1 test 1
[2] => test 2 test 2
[3] => test 3 test 3
)
I have found lots of functions like array_merge and array_combine but nothing that does what I want to do.
Any ideas?
Thanks in advance.
Max
You could do it with array_map:
$combined = array_map(function($a, $b) { return $a . ' ' . $b; }, $a1, $a2));
Here is a one line solution if you are using Php 5.3.0+:
$result = array_map(function ($x, $y) { return $x.$y; }, $array1, $array2);
Many answers recommend the array_map way, and many the more trivial for loop way.
I think the array_map solution looks nicer and "more advanced" than looping over the arrays and building the concatenated array in a for loop, BUT - contrary to my expectations - it is much slower than a regular for.
I've run some tests with PHP Version 7.1.23-4 on ubuntu 16.04.1: with two arrays each containing 250k elements of 10 digit random numbers a for solution took 4.7004 sec for 20 runs, while the array_map solution took 11.7939 sec for 20 runs on my machine, almost 2.5 times slower!!!
I would have expected PHP to better optimise the built in array_map feature, than a for loop, but looks like the opposite.
The code I've tested:
// Init the test
$total_time_for = 0;
$total_time_arraymap = 0;
$array1 = [];
$array2 = [];
for ( $i = 1; $i < 250000; $i ++ ) {
$array1[] = mt_rand(1000000000,9999999999);
$array2[] = mt_rand(1000000000,9999999999);
}
// Init completed
for ( $j = 1; $j <= 20; $j ++ ) {
// Init for method
$array_new = [];
$startTime = microtime(true);
// Test for method
for ( $i = 0; $i < count($array1); $i ++ ) {
$array_new[] = $array1[$i] . " " . $array2[$i];
}
// End of test content
$endTime = microtime(true);
$elapsed = $endTime - $startTime;
$total_time_for += $elapsed;
//echo "for - Execution time : $elapsed seconds" . "\n";
unset($array_new);
//----
// Init array_map method
$array_new = [];
$startTime = microtime(true);
// Test array_map method
$array_new = array_map(function($a, $b) { return $a . ' ' . $b; }, $array1, $array2);
// End of test content
$endTime = microtime(true);
$elapsed = $endTime - $startTime;
$total_time_arraymap += $elapsed;
//echo "array_map - Execution time : $elapsed seconds" . "\n";
unset($array_new);
}
echo "for - Total execution time : $total_time_for seconds" . "\n";
echo "array_map - Total execution time : $total_time_arraymap seconds" . "\n";
Question arises than what array_map is good for? One possible answer that comes into my mind, is what if we have a predefined function somewhere, maybe in a 3rd party library, we'd like to apply to the arrays and we don't want to reimplement that function inside our for loop. array_map seems to be convenient in that case, to apply that function on our arrays. But is it any better, than calling the function from a for loop?
I've tested this as well, and looks like truly, array_map excels when using predefined functions. This time array_map took 8.7176 sec, while for loop took 12.8452 sec to do the same job as above.
The code I've tested:
// Init the test
$total_time_for = 0;
$total_time_arraymap = 0;
$array1 = [];
$array2 = [];
for ( $i = 1; $i <= 250000; $i ++ ) {
$array1[] = mt_rand(1000000000,9999999999);
$array2[] = mt_rand(1000000000,9999999999);
}
function combine($a, $b) {
return $a . ' ' . $b;
}
// Init completed
for ( $j = 1; $j <= 20; $j ++ ) {
// Init for method
$array_new = [];
$startTime = microtime(true);
// Test for method
for ( $i = 0; $i < count($array1); $i ++ ) {
$array_new[] = combine($array1[$i], $array2[$i]);
}
// End of test content
$endTime = microtime(true);
$elapsed = $endTime - $startTime;
$total_time_for += $elapsed;
//echo "for external function call - Execution time : $elapsed seconds" . "\n";
unset($array_new);
//----
// Init array_map method
$array_new = [];
$startTime = microtime(true);
// Test array_map method
$array_new = array_map('combine', $array1, $array2);
// End of test content
$endTime = microtime(true);
$elapsed = $endTime - $startTime;
$total_time_arraymap += $elapsed;
//echo "array_map external function call - Execution time : $elapsed seconds" . "\n";
unset($array_new);
}
echo "for external function call - Total execution time : $total_time_for seconds" . "\n";
echo "array_map external function call - Total execution time : $total_time_arraymap seconds" . "\n";
So long story short, the general conclusion:
Calling a predefined function: use array_map, it takes ~40% less time (8.7 sec vs. 12.8 sec )
Implementing the array manipulation right where needed: use for loop, it takes ~60% less time (4.7 sec vs. 11.8 sec).
Have a choice between using a predefined function or (re-)implementing it right where needed: use for loop and implement the required manipulations inside the loop, it takes ~45% less time ( 4.7 sec vs. 8.7 sec. ).
Based on this, in your particular use-case, use for loop and do the concatenation inside the loop body, without calling other functions.
you can do it like
for($i; $i<count($a); $i++)
{
$arr[$i] = $a[$i]." ".$b[$i];
}
Just loop through and assign the concatenation to a new array:
$array1=array("test","test 1","test 2","test 3");
$array2=array("x","y","z","w");
$new_array=array();
foreach (range(0,count($array1)-1) as $i)
{
array_push($new_array,$array1[$i] . $array2[$i]);
}
Assuming the two arrays are $array1 and $array2
for($x = 0; $x < count($array2); $x++){
$array1[$x] = $array1[$x] . ' ' . $array2[$x];
}
If you have data coming from two different querys and they become two different arrays, combining them is not always an answer.
There for when placed into an array ([]) they can be looped with a foreach to count how many, then looped together.
Note: they must have the same amount in each array or one may finish before the other…..
foreach ($monthlytarget as $value) {
// find how many results there were
$loopnumber++;
}
echo $loopnumber;
for ($i = 0; $i < $loopnumber; $i++) {
echo $shop[$i];
echo " - ";
echo $monthlytarget[$i];
echo "<br>";
}
This will then display: -
Tescos - 78
Asda - 89
Morrisons - 23
Sainsburys - 46
You can even add in the count number to show this list item number....
There's no built-in function (that I know of) to accomplish that. Use a loop:
$combined = array();
for($i = 0, $l = min(count($a1), count($a2)); $i < $l; ++$i) {
$combined[$i] = $a1[$i] . $a2[$i];
}
Adapt the loop to your liking: only concatenate the minimum number of elements, concatenate empty string if one of the arrays is shorter, etc.
you loop through it to create a new array. There's no built-in function. Welcome to the wonderful world of programming :)
Hints:
http://pt2.php.net/manual/en/control-structures.foreach.php
You can combine two strings with "."

PHP date(): minutes without leading zeros

I'd like to know if there is a formatting letter for PHP's date() that allows me to print minutes without leading zeros, or whether I have to manually test for and remove leading zeros?
Use:
$minutes = intval(date('i'));
For times with more information than just minutes:
ltrim() - Strip whitespace (or other characters) from the beginning of a string
ltrim(date('i:s'), 0);
returns:
8:24
According to the PHP Documentation, the date() function does not have a placeholder for minutes without leading zeros.
You could, however, get that information by simply multiplying the dates, with a leading zero, by 1, turning it into an integer.
$minutesWithoutZero = 1* date( 'i' );
I tried to find this for seconds as well, gave up the search and just casting the result as a int like this:
echo (int)date("s");
That will get rid of the leading zero's in a fast efficient way.
Doesn't look like it, but you could do something like...
echo date('g:') . ltrim(date('i'), '0');
Alternately, you could cast the second call to date() with (int).
This also works
$timestamp = time(); // Or Your timestamp. Skip passing $timestamp if you want current time
echo (int)date('i',$timestamp);
I use this format if I need a XXmXXs format:
//Trim leading 0's and the 'm' if no minutes
ltrim(ltrim(gmdate("i\ms\s", $seconds), '0'), 'm');
This will output the following:
12m34s
1m23s
12s
i just did this one line solution
$min = intval(date('i',strtotime($date)));
Using ltrim method may remove all the leading zeroes.For ex if '00' min.In this case this will remove all the zeroes and gives you empty result.
My solution:
function seconds2string($seconds) {
if ($seconds == 0) {
return '-';
}
if ($seconds < 60) {
return date('0:s', $seconds);
}
if ($seconds < 3600) {
return ltrim(date('i:s', $seconds), 0);
}
return date('G:i:s', $seconds);
}
This will output:
0 seconds: -
10 seconds: 0:10
90 seconds: 1:30
301 seconds: 5:01
1804 seconds: 30:04
3601 seconds: 1:00:01
Just use this:
(int) date('i');
Or in mySQL just multiply it by 1, like such:
select f1, ..., date_format( fldTime , '%i' ) * 1 as myTime, ..., ...
$current_date = Date("n-j-Y");
echo $current_date;
// Result m-d-yy
9-10-2012
A quickie from me. Tell me what you think:
<?php function _wo_leading_zero($n) {
if(!isset($n[1])) return $n;
if(strpos($n, '.') !== false) {
$np = explode('.', $n); $nd = '.';
}
if(strpos($n, ',') !== false) {
if(isset($np)) return false;
$np = explode(',', $n); $nd = ',';
}
if(isset($np) && count($np) > 2) return false;
$n = isset($np) ? $np[0] : $n;
$nn = ltrim($n, '0');
if($nn == '') $nn = '0';
return $nn.(isset($nd) ? $nd : '').(isset($np[1]) ? $np[1] : '');
}
echo '0 => '._wo_leading_zero('0').'<br/>'; // returns 0
echo '00 => '._wo_leading_zero('00').'<br/>'; // returns 0
echo '05 => '._wo_leading_zero('05').'<br/>'; // returns 5
echo '0009 => '._wo_leading_zero('0009').'<br/>'; //returns 9
echo '01 => '._wo_leading_zero('01').'<br/>'; //returns 1
echo '0000005567 => '._wo_leading_zero('0000005567').'<br/>'; //returns 5567
echo '000.5345453 => '._wo_leading_zero('000.5345453').'<br/>'; //returns 0.5345453
echo '000.5345453.2434 => '._wo_leading_zero('000.5345453.2434').'<br/>'; //returns false
echo '000.534,2434 => '._wo_leading_zero('000.534,2434').'<br/>'; //returns false
echo date('m').' => '._wo_leading_zero(date('m')).'<br/>';
echo date('s').' => '._wo_leading_zero(date('s')).'<br/>'; ?>
use PHP's absolute value function:
abs( '09' ); // result = 9
abs( date( 'i' ) ); // result = minutes without leading zero
My Suggestion is Read this beautiful documentation it have all details of php date functions
Link of Documentation
And as per your question you can use i - Minutes with leading zeros (00 to 59) Which return you minutes with leading zero(0).
And Also introducing [Intval()][2] function returns the integer value of a variable. You can not use the intval() function on an object

Categories