Form date from foreach loop through object - php

So I have an array of objects that looks like this:
credit_cards[[0] => {expiration_date: {year: "17", month: "04"}]
What I try to do is somethings like this:
$years = [];
$months = [];
$dates = [];
foreach ($clients->settings->credit_cards as $key => $value){
$years[] = $value->expiration_date->year;
$months[] = $value->expiration_date->month;
}
I need to loop through every credit card in that array and make an array $dates that should form a basic date by concatenating years and months. So in this case it should look like this: $dates = ['2017-04']. But I have no idea how to do this. Any help is welcomed and some explanation if you may so I can understand how to do this in the future.

You can just add the dates with a minor amount of work. create a parseable string that represents your Month / Year. Then put it in php's strtotime(). That integer representing seconds since the epoch is the 2nd argument to format the four digit date -dash- month that you are looking for.
$years[] = $value->expiration_date->year;
$months[] = $value->expiration_date->month);
$my = $value->expiration_date->month.'/'.$value->expiration_date->year;
$dates[] = date('Y-m', strtotime($my));

You're looking for the concatenate operator: . (More info here.) You can build a formatted date string and pass it to strtotime like WEBjuju's answer, or move directly to using the concatenation.
$years[] = $value->expiration_date->year;
$months[] = $value->expiration_date->month;
$dates[] = $value->expiration_date->year . '-' . $value->expiration_date->month;

Related

Finding the average date given an array of PHP DateTime Objects

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 to include zero in a string?

How to count including the zero like substr in php. I'm doing like this query.
$datavariable = $query->result();
$caldata = array();
foreach ($datavariable as $row) {
$caldata[substr($row->start_date, 8, 2)] = $row->class;
}
If the date is 2019-05-06 it didn't get the 01-09 only the 10-up can you help me or is their a function like that? I just want to get the days
Don't use substr() to get the day from the date. Use date() and strtotime() for this
$day = date('d', strtotime($row->start_date));
$caldata[$day] = $row->class;
Read more about date() and strtotime()

Filter PHP Array Keys and calculating mean value

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.

PHP: Merge two date objects into one

I've got two date objects sent from a date input and a time input.
I want to generate a DateTime object with the yyyy-mm-dd from the date input and hh-mm from the time input.
Data sent from date input
[search_from_date] => 2015-08-04T23:00:00.000Z
Data sent from time input
[search_from_time] => 1970-01-01T02:02:00.000Z
I need to merge these two dates into:
2015-08-04 02:02
I've been playing around with exploding the string, etc to no avail,
Any help would be appriciated
Cheers
You can create two DateTime objects from your strings, then use the second to set the time on the first.
$arr = ['search_from_date' => '2015-08-04T23:00:00.000Z', 'search_from_time' => '1970-01-01T02:02:00.000Z'];
$date = new DateTime($arr['search_from_date']);
$time = new DateTime($arr['search_from_time']);
$date->setTime($time->format('H'), $time->format('i'), $time->format('s'));
echo $date->format('r');
Here's an eval.in with an example - https://eval.in/424209
you can split on "T" like that :
$search_from_date = "2015-08-04T23:00:00.000Z";
$search_from_time = "1970-01-01T02:02:00.000Z";
$tab_date = explode("T", $search_from_date);
$tab_time = explode("T", $search_from_time);
$date_time = new DateTime("$tab_date[0]T$tab_time[1]");
var_dump($date_time);
Try this,
$search_from_date = '2015-08-04T23:00:00.000Z';
$search_from_time = '1970-01-01T02:02:00.000Z';
$data = explode('T',$search_from_date);
$data1 = explode('T',$search_from_time);
$data1 = explode('.',$data1[1]);
echo $data[0].' '.$data1[0];
$time=new DateTime('1970-01-01T02:02:00.000Z');
$date=new DateTime('2015-08-04T23:00:00.000Z');
$newDateTime= new DateTime();
$newDateTime->setTime($time->format('H'),$time->format('i'),$time->format('s'));
$newDateTime->setDate($date->format('Y'),$date->format('m'),$date->format('d'));
echo $newDateTime->format('Y/m/d H:i'));
exit;
Something like this should work.
$finalDateD creates a date string for just the Year, month and day
and
$finalDateT creates a date string for just the Hours, minutes
This is then concatenated into the variable $finalDate;
$finalDateD = date('Y-m-d', strtotime($search_from_date));
$finalDateT = date('H:i', strtotime($search_from_time));
$finalDate = $finalDateD.' '.$finalDateT;

php, get the the highest-closest time to current from array? [duplicate]

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

Categories