I store dates in mysql databse in a date field like this......
09/03/2018|29/03/2018|17/06/2018|10/07/2018|28/10/2019|12/02/2019
In php I convert the above date formats into an array...
$currentyear= date("Y");
$this_month = array();
$other_month = array();
$dates_list = #explode("|", $dates_list);
$dates_list = str_replace(array("\r", "\n"), '', $dates_list);
foreach($dates_list as $date)
{
if(strstr($date,$month))
{
array_push($this_month,$date);
} else {
array_push($other_month,$date);
}
}
It's the $other_month array I wish to filter
So in the following array 09/03/2018|29/03/2018|17/06/2018|10/07/2018|28/10/2019|12/02/2019 it would only show the last two dates.
I would like to filter out all none "current year" dates, if anyone can help it would be greatly appreciated.
Thank you
I don't really prefer what you are doing DB wise, however to filter your array here is a script:
$this_year = [];
$other_years = [];
foreach ($dates_list as $date) {
if (date('Y', strtotime($date)) == date('Y')) {
$this_year[] = $date;
} else {
$other_years[] = $date;
}
}
Related
I want to get closest date from $search_date if is not same values in $array['date']. If is same value in $array['date'] I want all array.
Format date is 'Y-m-d'.
Example 1:
$search_date = '2022-12-08';
$array = [{"price":"200","date":"2022-12-12"},{"price":"50","date":"2022-12-10"},{"price":"100","date":"2022-12-10"}]
Return should be: [{"price":"50","date":"2022-12-10"},{"price":"100","date":"2022-12-10"}]
Example 2:
$search_date = '2022-12-08';
$array = [{"price":"200","date":"2022-12-08"},{"price":"50","date":"2022-12-09"},{"price":"100","date":"2022-12-11"}]
Return should be: [{"price":"200","date":"2022-12-08"}]
Example 3:
$search_date = '2022-12-08';
$array = [{"price":"200","date":"2022-12-10"},{"price":"100","date":"2022-12-10"},{"price":"50","date":"2022-12-11"}]
Return should be: [{"price":"200","date":"2022-12-10"},{"price":"100","date":"2022-12-10"}]
Example 4:
$search_date = '2022-12-08';
$array = [{"price":"200","date":"2022-12-08"},{"price":"100","date":"2022-12-08"},{"price":"50","date":"2022-12-08"}]
Return should be: [{"price":"200","date":"2022-12-08"},{"price":"100","date":"2022-12-08"},{"price":"50","date":"2022-12-08"}]
Thank you!
This code calculates the distance in days between $search and each record. It assumes that you want to find closest distance in both future and past.
<?php
/*
Question Author: Catalin Iamandei
Question Answerer: Jacob Mulquin
Question: PHP - get closest date from array
URL: https://stackoverflow.com/questions/74598442/php-get-closest-date-from-array
Tags: php, arrays, laravel, date, php-carbon
*/
$search = '2022-12-10';
$searchObj = new DateTime($search);
$records = json_decode('[{"price":"200","date":"2022-12-10"},{"price":"100","date":"2022-12-10"},{"price":"50","date":"2022-12-11"}]', true);
$distances = [];
foreach ($records as $index => $record) {
$recordObj = new DateTime($record['date']);
$daysDiff = $searchObj->diff($recordObj)->format("%r%a");
$distances[$index] = abs($daysDiff);
}
$minimumDiff = min($distances);
$output = [];
foreach ($distances as $index => $distance) {
if ($distance == $minimumDiff) {
$output[] = $records[$index];
}
}
echo json_encode($output, JSON_PRETTY_PRINT);
Yields:
[
{
"price": "50",
"date": "2022-12-09"
},
{
"price": "100",
"date": "2022-12-11"
}
]
If you only want to search for closest dates in the future, you need to remove the abs() function and then remove all negative entries in the $distances array before using min().
If you want to search for a specific value in your array have you tried
array_search($value, $array);
By this you can search for a specific value in your array
If you want to search the lowest value
try to for looping your array and check if the array is lower than the previous index and if the for loop has ended you have the lowest date
$lowest_date = null;
for ($i = 0; count($i); $i++) {
if ($array['date'] < $lowest_date) {
$lowest_date = $array['date'];
}
}
you dont have mentioned what todo with prior dates, eg. searching for '2022-12-07', how to tread 2022-12-06 and 2022-12-08, as the difference both is 1. You can calculate the datediff for each entry, get the min datediff and output elements with this datediff. eg :
<?php
$SearchDate = new DateTimeImmutable('2022-12-08');
$array = array ('{"price":"200","date":"2022-12-12"}',
'{"price":"50","date":"2022-12-10"}',
'{"price":"100","date":"2022-12-10"}');
$laResult = array();
foreach($array as $jsonO) {
$json = json_decode($jsonO);
$CompareDate = new DateTimeImmutable($json->{'date'});
$interval = date_diff($SearchDate, $CompareDate);
$laThis['date'] = $json->{'date'};
$laThis['diff'] = $interval->format('%a');
$laThis['origin'] = $jsonO;
$laResult[] = $laThis;
}
$min_diff = min( array_column( $laResult, 'diff') );
echo 'nearestDiff:'. $min_diff .PHP_EOL;
foreach($laResult as $laSingleResult) {
if($laSingleResult['diff'] == $min_diff) {
echo $laSingleResult['origin'] .PHP_EOL;
}
}
Here is my controller:
$my_query = Deathregister::query();
foreach ($request->query() as $key => $value)
{
$my_query->where($key, $value);
}
$my_query->get();
Now if i pass 'fromdate = 2020-10-30' and 'todate = 2021-11-07' i want all the data in bwtween these days. Is this possible?
You can use CarbonPeriod class of PHP.
To use it in Laravel
import it first
use Carbon\CarbonPeriod;
Then in the controller function use
$period = CarbonPeriod::create($request->from_dt,'1 day', $request->to_dt);
foreach ($period as $value) {
$reqDate = $value->format('d-M-Y');
//$reqDate will have the date you can change the format as per your requirement
}
You can use whereDate() method:
Deathregister::whereDate('date_field','>=', $request->input('fromdate'))
->whereDate('date_field','<=', $request->input('todate'))
->get();
The below code worked for me to sort date by given all the parameter with date.
$q = $request->query();
if ($q != NULL) {
$fromdate = $request->fromdate;
$todate = $request->todate;
$my_query = Movementregister::query();
if ($fromdate != NULL and $todate != NULL) {
if (!empty($q['type'])) {
$my_query->where('type', $q['type']);
}
if (!empty($q['issue'])) {
$my_query->where('issue', $q['issue']);
}
$my_query->whereBetween('created_at', [$fromdate, $todate]);
} else {
foreach ($request->query() as $key => $value) {
$my_query->where($key, $value);
}
}
$data = $my_query->get();
return response()->json(["message" => "Success", "data" => $data], 200);
}
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;
I'm trying to get the results of an array and move them to a $variable.
This is my current code:
<?php
$total_days_month = date('t'); // total days this month
// add "$currentday" day number to an array until $currentday<=$total_days_month
$days_array = array();
for ($currentday=1; $currentday<=$total_days_month; $currentday++) {
if ($total_days_month > $currentday)
{
array_push($days_array,"'$currentday',");
}
else
{
array_push($days_array,"'$currentday'");
}
}
// now transfer the array content to a $variable
$variable = ????
?>
$variable content must be '1', '2', '3', '4' ........ '31'
$variable = implode("','", $days_array);
<?php
$total_days_month = date('t'); // total days this month
// add "$currentday" day number to an array until $currentday<=$total_days_month
$days_array = array();
for ($currentday=1; $currentday<=$total_days_month; $currentday++) {
if ($total_days_month > $currentday){
array_push($days_array,"'$currentday',");
}else{
array_push($days_array,"'$currentday',");
}
}
// now transfer the array content to a $variable
$variable = implode(',', $days_array);
I am writing a PHP script where the inputs are:
From date
To date
I then want to take that date range and create an array of some sort that has:
Array(date,x)
As I add each date to the array, I will calculate the value that goes with it.
With .NET I would (off the top of my head) use a dictionary where the date was the key and x is the value.
The main task is getting that date range, then splitting that range into an array or dictionary of some sort (What would be ideal in php)
As i'm adding it to the array i'll run off some other code i've already wrote that calculate the value to go with that date
At the end of it all when it's added in there, i'll need to iterate through the array or list and add all the x values together.
(Untested)
function dateArray($from, $to, $value = NULL) {
$begin = new DateTime($from);
$end = new DateTime($to);
$interval = DateInterval::createFromDateString('1 day');
$days = new DatePeriod($begin, $interval, $end);
$baseArray = array();
foreach ($days as $day) {
$dateKey = $day->format("Y-m-d");
$baseArray[$dateKey] = $value;
}
return $baseArray;
}
$datesArray = dateArray('2011-01-01', '2011-03-31',true);
you can try this
function makeDateRange($from,$to,$pattern='m-d-y')
{
$day = date( $pattern , $from );
$to = date( $pattern , $to );
$parseDate = date_parse($from);
while( $day <= $to ) {
$day = mktime(0,0,0,$parseDate["month"],$parseDate["day"]+1,$parseDate["year"]);
$dateArray[] = date($pattern , $day);
}
return $dateArray;
}
// here make array
$keys = makeDateRange("12-01-11","12-02-11");
//here make above array as key in $a array
$a = array_fill_keys($keys, 'none');
print_r($a);
If I understand you correctly, you could use an associative array for that:
array(
'00-00-00' => $value,
'01-01-01' => $value,
// etc...
);
Or you can create it like this:
$myArray = array();
$myArray['00-00-00'] = $value;
$myArray['01-01-01'] = $value;
You could populate them by running a loop...