Split strings into an array of dates - php

I have an array of timestamps that I'm importing from different XML files. This is how they look like:
<field name="timestamp">2015-04-16T07:14:16Z</field>
So I have a bunch of them stored in an array named $timestamps like this:
2015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
I am only interested in the date part, not the time. I have tried splitting the string using the split() function.
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$dates = split ("T", $timestamps[$i]);
echo $dates[$i] . "<br>";
}
From what I understand it is storing the first part (before the T) then the part after the T. How can it store only the first part of each string?
When I try this:
echo $dates[1];
it outputs the first date fine. I'm not quite sure about the rest.
Any suggestions on a better way to accomplish this?
Thanks!

You should use strtotime and date, as opposed to string splitting and/or regex. This will help if your date format ever changes.
$dates = array();
foreach ($timestamps as $timestamp) {
$d = strtotime($timestamp);
$dates[] = date('Y-m-d', $d);
}
foreach ($dates as $date) {
echo $date . '<br/>';
}

I think splitting is not better the best is get date using date function easily. Very easy code:-
<?php
$dates = array('2015-04-16T07:14:16Z','2015-04-24T14:34:50Z','2015-04-25T08:07:24Z','2015-04-30T07:48:12Z','2015-05-02T08:37:01Z'); // i hope your dates array is like this
foreach($dates as $date){
echo date('Y-m-d',strtotime($date)).'<br/>';
}
?>
Output:- http://prntscr.com/78b0x4
Note:-I didn't take your whole array. Because it's easy to see and understand what i am doing there in my code. thanks.

You can simply use preg_replace() to remove all the "time" bits in the array:
$array = Array('2015-04-16T07:14:16Z', '2015-04-24T14:34:50Z', '2015-04-25T08:07:24Z');
// Remove "T" and anything after it
$output = preg_replace('/T.*/', '', $array);
print_r($output);
Outputs:
Array
(
[0] => 2015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
)

There's no reason to drag date and strotime into this, that's just extra overhead. You have an expected, regular format already.
And I would also give a warning about using date functions: you may run into trouble with the values changing after you put them through date and strtotime depending on your server's date/time(zone) settings! Since your strings do not specify the timezone offset, you won't even be able to properly convert.. you'll just have to roll with whatever your server is at or pick one yourself.
The safer way to ensure the actual value doesn't change is to just parse it as a string. Splitting at the "T" is fine. You're just having trouble with how to handle the variables. Here is an example:
// example data
$timestamps =<<<EOT
015-04-16T07:14:16Z
2015-04-24T14:34:50Z
2015-04-25T08:07:24Z
2015-04-30T07:48:12Z
2015-05-02T08:37:01Z
2015-05-09T10:41:45Z
2015-05-01T07:27:21Z
2015-05-07T09:41:36Z
2015-05-12T04:06:11Z
2015-05-12T05:52:52Z
2015-05-12T11:28:16Z
EOT;
$timestamps=explode("\n",$timestamps);
$dates = array();
for ($i=0; $i<count($timestamps); $i++){
$d = explode("T", $timestamps[$i]);
$dates[] = $d[0];
}
print_r($dates);
output:
Array
(
[0] => 015-04-16
[1] => 2015-04-24
[2] => 2015-04-25
[3] => 2015-04-30
[4] => 2015-05-02
[5] => 2015-05-09
[6] => 2015-05-01
[7] => 2015-05-07
[8] => 2015-05-12
[9] => 2015-05-12
[10] => 2015-05-12
)

Related

PHP: Iterating Through a multidimensional Array (4D)

I have a multidimensional array structured like below. It mimics a file structure that is storing files based on ./YEAR/MONTH/DAY/FILE.
Array
(
[2019] => Array
(
[05] => Array
(
[12] => Array
(
[0] => default.md
)
)
[12] => Array
(
[22] => Array
(
[0] => default.md
)
)
)
[2020] => Array
(
[05] => Array
(
[19] => Array
(
[0] => default.md
)
)
)
)
I am trying to loop through the entire array and get the values for each specific file while also getting the associated YEAR, MONTH and DAY for that specified file.
My loop is way off as I am trying to nest multiple foreach loops inside of a for loop. The further down the rabbit hole I get, the more issues I encounter
$post_search = directoryArrayMap("content"); //function that creates the array
$year = array_keys($post_search);
for($i = 0; $i < count($post_search); $i++ ) {
echo $year[$i] . "<br>";
foreach($post_search[$year[$i]] as $month => $day ) {
echo $month[$i] . "<br>";
foreach($post_search[$key[$month[$i]]] as $day => $post_file ) {
echo $day . "<br>";
}
}
}
I am looking for the best way to iterate through a multidimensional array. Thanks. My desired output would be something like:
File A:
Year: 2020
Month: 05
Day: 12
File B:
Year: 2019
Month: 12
Day: 22
File C:
Year: 2019
Month: 05
Day: 19
The goal is to run this in conjunction with another loop that checks "is_file" and display the output.
By using a series of nested foreach with key => value iterators you can get the output you want; the key is not to output the date parts until you get to the bottom of the loops:
foreach ($post_search as $year => $months) {
foreach ($months as $month => $days) {
foreach ($days as $day => $files) {
foreach ($files as $file) {
echo "File $file:\nYear: $year\nMonth: $month\nDay: $day\n";
}
}
}
}
Output (for your sample data):
File default.md:
Year: 2019
Month: 5
Day: 12
File default.md:
Year: 2019
Month: 12
Day: 22
File default.md:
Year: 2020
Month: 5
Day: 19
Demo on 3v4l.org
Using functions to handle the confusing nested aspect should help a lot. By no means is my example a robust solution. And personally, I'd probably put the functions in a class & make it object oriented... but that's definitely not the right solution for every case.
You'll have to adapt this, but hopefully the concept is helpful.
function handleYear($year,$arrOfMonths){
echo $year;
foreach ($arrOfMonths as $month=>$arrOfDays){
handleMonth($month,$arrOfDays);
}
}
function handleMonth($month,$arrOfDays){
echo $month;
foreach ($arrOfDays as $dayOfMonth=>$listOfFiles){
handleDay($dayOfMonth,$listOfFiles);
}
}
//to get started
foreach ($data as $year=>$arrOfMonths){
echo $year;
handleYear($year, $arrOfMonths);
}
You could also modify the sub-functions to accept the parent paramaters. Like handleMonth could also take in the year, then handleYear just passes $year along.
EDIT:
After seeing your desired output... I'd suggest passing the year & month down to the handleDay function. Then handleDay could be something like:
function handleDay($day,$arrOfFiles,$year,$month) use (&$files){
foreach ($arrOfFiles as $index=>$fileName){
$file = ['year'=>$year,'month'=>$month,'day'=>$day];
$files[] = $file;
}
}
You would then need to declare $files = [] outside the function, before declaration of handleDay if I'm not mistaken.
But then you'd just have an array of files that you could work with pretty easily.
Personally, I'd probably toil away for awhile to come up with a cleaner solution (Not fond of the use statement in this case, which I might not even be using correctly). If it's in a class, then you could use $this->files instead of the use (&$files).

How to change/reset PHP array type?

I have the following PHP code working to identify intersections of dates that fall on dates where we have a Full condition.
Based on this StackOverflow post :
php check multiple dates in array are within a date range
I have a working filter using a test array ($d2).
<?php
$d2 = array ('08/23/2019','08/24/2019','08/25/2019','08/26/2019','08/27/2019','08/28/2019','08/29/2019','08/30/2019','08/31/2019','09/01/2019');
$start = strtotime('08/27/2019');
$end = strtotime('08/29/2019');
foreach($d2 AS $date) {
$timestamp = strtotime($date);
if($timestamp >= $start && $timestamp <= $end) {
echo "The date $date falls on a day where we are sold out \n";
} else {
// echo "Process Reservation \n";
}
}
?>
The print_r($d2) that works looks like this:
Array
(
[0] => 08/23/2019
[1] => 08/24/2019
[2] => 08/25/2019
[3] => 08/26/2019
[4] => 08/27/2019
[5] => 08/28/2019
[6] => 08/29/2019
[7] => 08/30/2019
[8] => 08/31/2019
[9] => 09/01/2019
)
But my array which is comprised of checking existing dates, then finding which have x number of instances on a particular date. For instance, if we have 7 or more we have a full condition (sold out).
$sold_outUS = array_filter($datesUS, function($n) { return $n >= 7; });
If I print_r($sold_outUS) this array, it shows a different type of array structure:
Array
(
[08/23/2019] => 7
[08/24/2019] => 7
[08/25/2019] => 7
[08/26/2019] => 7
[08/27/2019] => 7
[08/28/2019] => 7
[08/29/2019] => 7
[08/30/2019] => 7
[08/31/2019] => 7
[09/01/2019] => 7
)
How do I change the way this array is stored so it matches the working state and what is happening that I need to learn?
Looks as though I need an independent key and value for each instance in the array. Just don’t know how to change or reset the array to be? non-multi-dimensional?
Use array_keys to get the keys of an associative array.
$sold_outUS = array_keys(array_filter($datesUS, function($n) { return $n >= 7; }));

How to loop with condition

This is my $update array
Array
(
[0] => 08:31:08
[1] => 08:32:08
[2] => 08:33:08
[3] => 10:34:08
[4] => 08:51:08
[5] => 08:21:08
[6] => 10:39:08
[7] => 08:41:08
[8] => 08:49:08
[9] => 08:20:08
[10] => 08:11:08
[11] => 10:50:08
)
This is my code
$default_computed = 9:30:00
$timin ="";
for ($x=0; $x < count($update) ; $x++) {
if (strtotime($update[$x]) > strtotime($default_computed) ) {
$timin .= $update[$x].',';
$replace_timin = substr_replace($timin ,"",-1);
$updated_timin = explode(",",$replace_timin);
$late_time_in = count($updated_timin);
echo "<pre>";
print_r($update);
print_r($timin);
die();
}
}
i want this output but its stop already for 1 time
10:34:08,10:39:08,10:50:08,
how can i loop continuously to get my target output?
I'm assuming your script is trying to figure out which time inside the array is beyond the cutoff time (which is $default_computed = 9:30:00).
With this in mind, I'd suggest you take on a different approach on this problem and avoid string manipulations (using substr_replace, explode and such) and start using DateTime classes instead:
$default_computed = '9:30:00'; // cutoff time
$cutoff = new DateTime($default_computed); // using DateTime
foreach ($update as $time) { // so each time element inside the array
$time_in = new DateTime($time); // load each time
if ($time_in >= $cutoff) { // if this time is beyond the cutoff
echo $time_in->format('H:i:s'); // output it
}
}
They're much easier and straightforward to use since you just load in the time and you can compare DateTime to DateTime objects directly in the if conditions.
So its basically each time in inside the array compared to the cutoff time.
$update = array
(
'08:31:08',
'08:32:08',
'08:33:08',
'10:34:08',
'08:51:08',
'08:21:08',
'10:39:08',
'08:41:08',
'08:49:08',
'10:50:08'
);
$default_computed = '9:30:00';
$default_computed= date("H:i:s", strtotime($default_computed)); // Convert your string to time
for($i=0; $i < count($update) ; $i++){
$update[$i]= date("H:i:s", strtotime($update[$i])); //Convert each elements of the array into time format
if($update[$i]>$default_computed)
echo $update[$i].",";
}

converting each element of array into time using date() in php

i have an array in php like the one given below
$each_session_time=array("2700","3356","3278","5452");
the issue is i want to convert each element in this array into time
i tried using
date("h:i:s",$each_session_array);
but it didn't work because date function doesn't work with arrays...
so can anyone help me in converting the each element into time....I shall be very thankful to you
$each_session_time=array();
for ($i=0; $i<sizeof($array_in_time_str) ; $i++) {
$each_session_time[$i]=$array_out_time_str[$i]-$array_in_time_str[$i];
}
If I understood your request, then this is what you need : using array_map here is a demo
<?php
$each_session_time=array(2700,33522,2222278,1111452);
$res = array_map(function($elem){
return date ("H:i:s",$elem);
},$each_session_time);
print_r($res);
?>
you can try this.
$each_session_time=array("2700","3356","3278","5452");
foreach ($each_session_time as $key => $value) {
$timeArray[] = date("h:i:s",$value);
}
echo "<pre>";print_r($timeArray);
Output:
Array
(
[0] => 06:15:00
[1] => 06:25:56
[2] => 06:24:38
[3] => 07:00:52
)

Sort array with timestamps?

I have an array of timestamps that look like this:
2012-11-19 19:45
I need to sort them by date. I could do a bubble sort or something if i could get the unix timestamp of a date, but i don't know what function gives me that. I looked at strtotime but it won't let me pass a date format. I'm also not sure a bubble sort is the best way to go.
Any suggestions?
Array example:
Also, sorry, i should have mentioned it was in 'show_date'.
Array
(
[15] => Array
(
[show_date] => 2012-11-19 10:40
)
[16] => Array
(
[show_date] => 2012-11-20 10:40
)
[17] => Array
(
[show_date] => 2012-11-21 10:40
)
[18] => Array
(
[show_date] => 2012-11-22 10:40
)
)
No need to overcomplicate this. Just use the built-in sort function:
sort($timestamp_array);
You don't need to convert to UNIX timestamps because the strings are in the standard "ISO sortable date" format. That means that if you sort the strings, the dates will be in the correct order.
Here is a php -a session that shows how it works:
php > $ts = array('1986-01-31 12:11', '2012-01-01 13:12', '1980-10-10 12:00');
php > sort($ts);
php > echo var_export($ts);
array (
0 => '1980-10-10 12:00',
1 => '1986-01-31 12:11',
2 => '2012-01-01 13:12',
)
You can just sort it with PHP standard sort. See Sorting Arrays
asort($timestamps);
For your example, you can define a comparison function
function cmp_show_date($a, $b)
{
if ($a['show_date'] == $b['show_date']) {
return 0;
}
return ($a['show_date'] < $b['show_date']) ? -1 : 1;
}
and use that in usort
usort($timestamps, 'cmp_show_date');
You could use a combination of usort() and strtotime, but I'd rather use the DateTime class and its getTimestamp method because it can handle time zones and several formats.
You do not need date format to pass that particular date. When you pass strtotime('2012-11-19 19:45'); it will return UNIX time stamp.
EDIT:
$arr = array();
foreach ($dates as $k => $v) {
$arr[$k] = strtotime($v['date']);//or $k if your date is the index
}
array_multisort($arr, SORT_ASC, $dates);

Categories