php get closest timestamp but less than current timestamp - php

I'm working with timestamp in an array as value, for example :
1455874500 : 19/02/2016 09h35
1455879600 : 19/02/2016 11h00
1455921300 : 19/02/2016 22h35
And the thing I would like to do is to get the closest timestamp from my array BUT if this timestamp is higher than the current timestamp (closest > current timestamp), get the lower value.
Here is an example to illustrate my point, it's 19/02/2016 10h58, I don't want to get 1455879600 (19/02/2016 11h00) but 1455874500 (19/02/2016 09h35) AND then, when it is 19/02/2016 11h00, get 1455879600.
I've been working on this code :
function find_closest($id, $date_now){
global $cnx;
$sql = "select position_history from worksheets WHERE id = $id LIMIT 1";
$stmt = $cnx->prepare($sql);
try {
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_OBJ);
}
catch (PDOException $e) {
echo $e->getMessage();
}
$pos_lane = unserialize($result->position_history);
$i=0;
$array = array();
foreach ($pos_lane as $item) {
// $exp[2] : timestamp
$exp = explode("|", $pos_lane[$i]);
$array[$exp[1]] = $exp[2];
$i++;
}
$mostrecent = "0";
foreach($array as $timestampmove)
{
if ($timestampmove > $mostrecent && $timestampmove < $date_now) {
$mostrecent = $timestampmove;
}
}
$closeto = array_search($mostrecent,$array);
return $closeto;
}
which aim to select the most recent timestamp BEFORE today but it does not seem to work as I want...
Maybe you have a better solution for me?
thank you !

Why not make it simpler and have the original sql query do the work for you?
$sql = "select MAX(position_history) from worksheets WHERE id = $id and position_history < now() LIMIT 1";

You may try the following:
foreach ($pos_lane as $item) {
// $exp[2] : timestamp
$exp = explode("|", $pos_lane[$i]);
$array[$exp[1]] = (int) $exp[2]; // <<< cast to int
$i++;
}
$mostrecent = 0;
$closeto = null;
foreach($array as $key => $timestampmove)
{
if ($timestampmove < $date_now) { // <<< make sure $date_now is a Unix timestamp
if ($mostrecent < $timestampmove) {
$mostrecent = $timestampmove;
$closeto = $key;
}
}
}
return $closeto;

Related

Remove Duplicated Entries From an Array

For removing the duplicated entries I know I have to use array_unique() but unfortunately by using this I got unexpected result(s). My PHP code is this:
$query = $db->query("
SELECT sid,father_contact,residential_contact
FROM ".TABLE_PREFIX."student_list
{$where_clause}
ORDER BY sid ASC");
while ($s = $db->fetch_array($query))
{
if (!empty($s['father_contact']))
{
$father_contact = $s['father_contact'].', ';
}
else
{
$father_contact = '';
}
if (!empty($s['residential_contact']))
{
$residential_contact = $s['residential_contact'].', ';
}
else
{
$residential_contact = '';
}
$phone_nums_bit .= $father_contact.$residential_contact;
}
This grabs all phone numbers from the database tables and print the result like this:
03334523675, 03124237009, 03134237002, 03124237009, 03217832173, 03134237002, 3134237002, 03124237009,
Notice that few numbers like 03134237002 is repeating thrice. I want to remove duplicate entries from this result. Please help me to sort it out. Thanks.
You can try to do it via array structures. Just to give you an idea:
$phones = [];
while ($s = $db->fetch_array($query))
{
if (!empty($s['father_contact']))
{
$phones[] = $s['father_contact'];
}
if (!empty($s['residential_contact']))
{
$phones[] = $s['residential_contact'];
}
}
$phones = array_unique($phones);
// and then combine into string
$phone_nums_bit = implode(', ', $phones);

How do I detect the last iteration in while loop

I tried doing this first:
$e = 0;
$objectsid = mysql_query("SELECT * FROM xw_char_items WHERE CharId = '$charid' AND ItemCat = 'object' ORDER BY SortOrder ASC");
while($obj = mysql_fetch_array($objectsid)) {
$e++;
if($e==9) break;
$objectsinfo = mysql_query("SELECT * FROM xw_objects WHERE ItemId = '{$obj["ItemId"]}'");
$object = mysql_fetch_array($objectsinfo);
echo "&charid$e={$char["Id"]}";
if($objectsid == end($obj)) {
echo "&intActiveObject=1";
echo "&intObjectsNum=$e";
}
}
Here it never detects the last one. I also tried this:
$e = 0;
$len = count($objectsid));
while($obj = mysql_fetch_array($objectsid)) {
$e++;
if($e==9) break;
$objectsinfo = mysql_query("SELECT * FROM xw_objects WHERE ItemId = '{$obj["ItemId"]}'");
$object = mysql_fetch_array($objectsinfo);
mysql_free_result($objectsinfo);
echo "&charid$e={$char["Id"]}";
if ($e == $len - 1) {
echo "&intActiveObject=1";
echo "&intObjectsNum=$e";
}
}
Here it detects every iteration as the last one.
Does anyone how to make it detect the last iteration?
The $objectsid variable is storing the mysql_result object not the array of your fetched rows. So even if you apply count($objectsid), you will not get the length of your fetched array.
So the right method is to use mysql_num_rows().
So Simply do this $len=mysql_num_rows($objectsid); and the rest will workout as you are expecting. :)

PHP prepared statement concatenate: "comma", "and", and "period" from while loop

I'm trying to build a sentence from a MySQL query. I believe I have the concatenate part working, as I've substituted a static array in. Might anyone guide me in the right direction as to what my while loop would look like to produce the needed array? How can I create an associative array from my mysql statement?
$query = "SELECT name, dob FROM children WHERE personal_id = ?";
$statement = $db->prepare($query);
$statement->bind_param('i', $_SESSION['mysqlID']);
$statement->bind_result($name, $dob);
$statement->execute();
// Store the results
$statement->store_result();
// Get the number of rows
$num_of_rows = $statement->num_rows;
**//I believe my problem lies in this array ?**
$m_children = [];
while ($statement->fetch()) {
$m_children[] = $name;
$m_children[] .= $dob;
}
$num_children = intval($num_of_rows);
$children = [];
foreach ($m_children as $k => $v) {
$dob = strtotime($dob[$k]);
$children[] = "$v, born on {$dob}";
}
$tmp = array_pop($children);
if ($num_children > 1) {
$children_type = 'children';
$children = join(', ', $children) . ' and ' . $tmp;
} else {
$children_type = 'child';
$children = $tmp;
}
$children = "<p>I have the following ". $children_type .": ". $children .".</p>";
Overall your code looks okay. The grammatical parts are certainly solid (pop the last element, join the rest with commas etc...)
As you suspect, your problem code is that part that you've marked.
//I believe my problem lies in this array ?
$m_children = [];
while ($statement2->fetch()) {
$m_children[] = $name;
$m_children[] .= $dob;
}
$num_children = intval($num_of_rows);
$children = [];
foreach ($m_children as $k => $v) {
$dob = strtotime($dob[$k]);
$children[] = "$v, born on {$dob}";
}
Here's a suggested improvement:
$children = [];
while( $statement2->fetch()) {
$children[] = $name." born on ".date("d/M/Y",strtotime($dob));
}
$num_children = count($children);
There's no need to do two passes on the data, and you will need to format out the date of birth (otherwise you just get a timestamp). This code can then continue on to your grammatical formatting, which seems just fine to me.

json_encode returning the next rows values - PHP PDO SQL HighCharts

When trying to use json_encode from arrays in foreach() the data moves in to the next values, for example:
I have this table which is coming from the same query + php:
when using json_encode to try and fit this tables data in to highcharts, my outcome is like this:
[{"name":"User1","data":[0,2,0,0]},{"name":"User2","data":[0,2,0,0,2,0,2,4]}]
So it's moving User1's data in to User2's
My desired outcome would be:
[{"name":"User1","data":[0,2,0,0]},{"name":"User2","data":[2,0,2,4]}]
This is my code:
$uniqueHours = array();
$series = array();
$data = array();
foreach ($pdo->query("SELECT DATEPART(HOUR, AL.EndDateTime) AS 'EndHour'
FROM ActivityLog AL
WHERE
".$where."
ORDER BY AL.EndDateTime, 'EndHour' DESC") as $row)
{
if ( in_array($row['EndHour'], $uniqueHours) ) {
continue;
}
$uniqueHours[] = $row['EndHour'];
}
$ODsql = "SELECT * FROM Users";
foreach ($pdo->query($ODsql) as $row)
{
echo '<tr>';
$SCardNumber = $row['CardNumber'];
$SEmployeeName = $row['Username'];
echo '<td>'.$SEmployeeName.'</td>';
$chartValues = "";
foreach($uniqueHours as $hour)
{
$countSQL= $pdo->prepare("SELECT DISTINCT(COUNT(AL.TerminalNumber)) AS TOTALS
FROM ActivityLog AL, WavePick WP
WHERE AL.TransactionType = 'SPK' AND WP.PickedQty > 0
AND DATEPART(HOUR, AL.EndDateTime) = ".$hour."
AND AL.StartDateTime >= '".$StartDate." 00:00:00.000' AND AL.EndDateTime <= '".$StartDate." 23:59:59.000'
AND AL.OrderNumber = WP.OrderNumber
AND AL.CardNumber = '".$SCardNumber."'
");
$countSQL->execute();
$result = $countSQL->fetch(PDO::FETCH_OBJ);
$row_count = $result->TOTALS;
$totals[] = $result->TOTALS;
echo '<td>'.$row_count.'</td>';
}
echo '</tr>';
$series['name'] = $SEmployeeName;
$series['data'] = $totals;
array_push($data,$series);
}
I haven't actually put this in to the chart yet because the data is invalid.
I am using this to return the outcome:
echo "<div class='well'>";
print json_encode($results, JSON_NUMERIC_CHECK);
echo "</div>";
How can I make this data show only for each user it is linked to?
Before this loop:
foreach($uniqueHours as $hour)
empty $total array with
$total=array();
foreach($uniqueHours as $hour)

Searching Array in PHP and return results

Can't find quite the right answer so hope someone can help. Basically want to create an array and then return the results from a search e.g.
$tsql = "SELECT date, staffid, ID,status, eventid, auditid from maincalendar";
$params = array();
$options = array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$stmt = sqlsrv_query( $conn, $tsql , $params, $options);
$calarray=array();
while($row = sqlsrv_fetch_array($stmt)) {
$rowresult = array();
$rowresult["status"] = $row['status'];
$rowresult["eventid"] = $row['eventid'];
$rowresult["caldate"] = $row['date'];
$rowresult["staffid"] = $row['staffid'];
$rowresult["ID"] = $row['ID'];
$rowresult["auditid"] = $row['auditid'];
$calarray[] = $rowresult;
}
I would then like to search for values matching 'caldate' and 'staffid' and return the associated entry in $calarray
I suggest the following,
Fetch all data needed for the current month you are showing, using col BETWEEN x AND y
Add them to a array in PHP, with staffid and caldate as key
Something like so;
$calarray[$row['staffid'] . '-' . $row['date']][] = $row;
Not sure if a single staffid/date combination can have one or more events per day, if not you can remove the []
To check if we have information for a specific staffid/date combination, use isset
if (isset($calarray[$staffid . '-' . $mydate]) { ... }
Add indexes to the fields you're going to query, and then move the search to the sql query. You can also make simple filtering inside the loop. So you'll be populating several arrays instead of one, based on the search you need.
try this:
$matches = array();
$caldate = //your desired date;
$staffid = //your desired id;
foreach($calarray as $k => $v){
if(in_array($caldate, $v['caldate']) && in_array($staffid, $v['staffid'])){
$matches[] = $calarray[$k];
}
}
$matches should be and array with all the results you wanted.
also:
while($row = sqlsrv_fetch_array($stmt)) {
$rowresult = array();
$rowresult["status"] = $row['status'];
$rowresult["eventid"] = $row['eventid'];
$rowresult["caldate"] = $row['date'];
$rowresult["staffid"] = $row['staffid'];
$rowresult["ID"] = $row['ID'];
$rowresult["auditid"] = $row['auditid'];
$calarray[] = $rowresult;
}
can be shortened into:
while($row = sqlsrv_fetch_array($stmt)) {
$calarray[] = $row;
}
Maybe this code snipplet solves your problem.
I am not a PHP programmer, so no warrenty.
function searchInArray($array, $keyword) {
for($i=0;$i<array.length();$i++) {
if(stristr($array[$i], $keyword) === FALSE) {
return "Found ".$keyword." in array[".$i."]";
}
}
}

Categories