I have an option page with 2 fields.
A number field for the time interval:
booking_settings_openings_hours_interval
And a repeater field with 2 subfields:
booking_settings_opening_hours_start
booking_settings_opening_hours_end
The code below creates a list of all times (with interval X) from START to END time to populate a select field. The interval code works great but it doesn’t populate the select field with these time options.
But when I replace:
// explode the value so that each line is a new array piece
$choices = explode("\n", $choices);
With this:
// explode the value so that each line is a new array piece
echo explode("\n", $choices);
it does populate the select field but that’s not the way how to do it right..?
function yl_load_booking_time_field_choices( $field ) {
// reset choices
$field['choices'] = array();
$minutes = get_field('booking_settings_openings_hours_interval', 'booking_settings');
// get the value from options page without any formatting
if( have_rows('booking_settings_opening_hours', 'booking_settings') ) :
while ( have_rows('booking_settings_opening_hours', 'booking_settings') ) : the_row();
$start = get_sub_field('booking_settings_opening_hours_start', 'booking_settings');
$end = get_sub_field('booking_settings_opening_hours_end', 'booking_settings');
$startDate = DateTime::createFromFormat('H:i', $start);
$endDate = DateTime::createFromFormat('H:i', $end);
$interval = new DateInterval('PT'.$minutes.'M');
$dateRange = new DatePeriod($startDate, $interval, $endDate);
$choices = array();
foreach ($dateRange as $date) {
$dates = $date->format('H:i');
$choices[] = $dates;
}
// explode the value so that each line is a new array piece
$choices = explode("\n", $choices);
// remove any unwanted white space
$choices = array_map('trim', $choices);
// loop through array and add to field 'choices'
if( is_array($choices) ) {
foreach( $choices as $choice ) {
$field['choices'][ $choice ] = $choice;
}
}
endwhile;
endif;
// return the field
return $field;
}
add_filter('acf/load_field/name=booking_time', 'yl_load_booking_time_field_choices');
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;
}
}
I'm trying to work out how I can remove all timestamps which have a certain reservation id after them.
Currently I can unset only based on timestamp and not check whether reservation id is there. This is part of the php code snippet:
$pending_prep_dates_array = array();
$check_in_date = get_post_meta( $resID, 'reservation_checkin_date', true );
$check_out_date = get_post_meta( $resID, 'reservation_checkout_date', true );
$check_in_prep = new DateTime($check_in_date);
$check_in_prep->sub(new DateInterval('P2D')); // P1D means a period of 1 day
$check_in_final = $check_in_prep->getTimestamp();
$check_out_prep = new DateTime($check_out_date);
$check_out_prep->add(new DateInterval('P2D')); // P1D means a period of 1 day
$check_out_final = $check_out_prep->getTimestamp();
for ($currentDate = $check_in_final; $currentDate <= $check_out_final; $currentDate += (86400)) {
$Store = $currentDate;
unset($pending_prep_dates_array[$Store]);
This is how it is stored in array in my database:
a:15{i:1652054400;i:8997;i:1652140800;i:8999;i:1652227200;i:8999;i:1652313600;i:8999;i:1652400000;i:8999;i:1652486400;i:8999;i:1652572800;i:8999;i:1651536000;i:8993;i:1651622400;i:8993;i:1651708800;i:8993;i:1651795200;i:8993;i:1651881600;i:8993;i:1651968000;i:8997;i:1651363200;i:8993;i:1651449600;i:8993;}
So to clarify, how can I only remove timestamps if reservation id is for example 8999?
Thanks
You can iterate through the data and build a new array with the ID(s) removed:
<?php
$raw = 'a:15:{i:1652054400;i:8997;i:1652140800;i:8999;i:1652227200;i:8999;i:1652313600;i:8999;i:1652400000;i:8999;i:1652486400;i:8999;i:1652572800;i:8999;i:1651536000;i:8993;i:1651622400;i:8993;i:1651708800;i:8993;i:1651795200;i:8993;i:1651881600;i:8993;i:1651968000;i:8997;i:1651363200;i:8993;i:1651449600;i:8993;}';
$data = unserialize($raw);
$ids_to_remove = [8999, 8993];
$data_with_id_removed = [];
foreach ($data as $timestamp => $id) {
if (in_array($id, $ids_to_remove))
continue;
$data_with_id_removed[$timestamp] = $id;
}
var_dump($data_with_id_removed);
Result (all timestamps with id 8999 and 8993 removed)
array(2) {
[1652054400]=>
int(8997)
[1651968000]=>
int(8997)
}
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;
}
}
i have a code where it is to create an array key of the date which will group together and array value that will count the number of different id.. this is will be done when a user selects a "TO" and "FROM" date.. so as i was doing some testing i noticed something weird that the array only limits until 10 value. for example if i select date between 1/3/2018 - 20/3/2018 then it only returns from 1/3/2018 - 10/3/2018. why is this happening when i did not set any limit to it.
my code in controller:
public function graphheheByDate(Request $request, $companyID)
{
$companyID = $this->decode($companyID);
$matchs = DiraChatLog::whereBetween('date_access', [$request->from, $request->to])->orderBy('date_access', 'asc')->get();
foreach ($matchs as $key => $match) {
$time = strtotime($match->date_access);
$newformat = date('Y-m-d',$time);
$a[$newformat] = $this->testing($newformat,$match);
}
dd($a);
$user = array_values($a);
$dates = array_keys($a);
// dd($user, $dates);
$from = $request->from;
$to = $request->to;
// dd($from, $to);
$companyID = $this->encodeID($companyID);
return view('AltHr.Chatbot.graphhehe', compact('companyID','from','to', 'dates'))->with('user',json_encode($user,JSON_NUMERIC_CHECK))->with('dates',json_encode($dates,JSON_NUMERIC_CHECK));
}
private function testing($date,$match)
{
$a = Carbon::parse($date)->addDay()->toDateTimeString();
// dd($a,$date);
$noOfUsers = DiraChatLog::whereBetween('date_access', [$date,$a])->get();
// dd($noOfUsers);
return $noOfUsers->groupBy('user_id')->count();
}
using this i have selected the dates 1/3/2018 - 20/3/2018 but its returning like
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...