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].",";
}
Related
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; }));
let's say i have an php array like that:
Array ( [0] => 2017-08-25 06:27:00 [1] => 2017-08-25 07:38:00 [2] => 2017-08-25 08:34:00 [3] => 2017-08-25 09:57:00 [4] => 2017-08-25 11:08:00 [5] => 2017-08-25 12:37:00 [6] => 2017-08-25 14:12:00 [7] => 2017-08-25 15:21:00 [8] => 2017-08-25 16:59:00 [9] => 2017-08-25 18:08:00 [10] => 2017-08-25 19:05:00 [11] => 2017-08-25 20:03:00 [12] => 2017-08-25 21:04:00 [13] => 2017-08-25 21:59:00 [14] => 2017-08-25 23:02:00 )
And want to calculate the time in minutes between each timestamp in the array.
Output should be
Array ( [0] => 69 [1] => 56 [2] .... )
I have no Idea how to solve that for example with an foreach.
I've had a quick go, just looping through and checking if there's a next value, then subtracting it, and dividing by 60 to get minutes:
$dates = ['2017-08-25 06:27:00', '2017-08-25 07:38:00', '2017-08-25 08:34:00', '2017-08-25 09:57:00'];
$values = [];
foreach ($dates as $index => $date) {
$date = strtotime($date);
if (!empty($dates[$index+1])) {
$nextDate = strtotime($dates[$index+1]);
$values[] = ($nextDate-$date) / 60;
}
}
var_dump($values);
Even though the answer has already been accepted, I thought I'd give my input nonetheless as I feel there are other options that are more robust and clear/easier to understand.
The Object-Oriented Approach
PHP has a collection of native objects specifically designed to handle date calculations, namely DateTime and DateInterval. making use of those objects will make the code easier to read and understand, which in turn means the code is easier to bug and more maintainable.
$dateArr = ['2017-08-25 06:27:00', '2017-08-25 07:38:00', '2017-08-25 08:34:00'];
$previousDate = '';
foreach($dateArr as $dateStr) {
$curDate = new DateTime($dateStr);
if(!empty($previousDate)) {
$diff = $previousDate->diff($curDate);
echo $diff->format('%i min').PHP_EOL;
}
$previousDate = $curDate;
}
This loop will output the following:
11 min
56 min
Of course, if you want to use this value for calculations, you'll need to do some extra manipulation to turn it into a numeric value type.
$min = $diff->format('%i');
if(is_numeric($min)) {
$min = (int) $min;
echo $min.' ('.gettype($min).')'.PHP_EOL;
}
else {
echo 'Oops, something went wrong :('.PHP_EOL; // good place to throw an exception, this echo is only for demo purposes
}
Outputs:
11 (integer)
56 (integer)
Using the DateTime object will also allow you to catch badly formatted dates much more easily as it throws an exception instead of failing silently.
try {
$wrongDate = new DateTime('foobar');
echo $wrongDate->format('Y-m-d h:i:d').PHP_EOL;
}
catch(Exception $e) {
echo $e->getMessage().PHP_EOL; // the exception is caught
}
try {
$wrongToTime = strtotime('foobar');
echo $wrongToTome.PHP_EOL; // no exception si thrown and
// an undefined variable notice is thrown
}
catch(Exception $e) {
echo $e->getMessage().PHP_EOL;
}
Try it here!
Related Documentation
DateTime class
DateInterval class
DateInterval::format() function
strotime()
Convert the strings into timestamps (seconds) using strtotime or strptime, then simply subtract.
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
)
I'm trying to query our database to get all records that match the user defined query, and store the data in a formatted array. The problem is, I'm getting all of the records, but not really sure how to process the data appropriately. I've been working on this for a few days now and haven't made much head way after trying a variety of ideas. Hopefully, someone here will have some insight to share.
The code below executes the query and starts processing the returned data into the array:
$msg_vol = array();
$xy_coords = array();
$tweet_count = 1;
$query = "SELECT created_at, tweet_id FROM `tweets` WHERE tweet_text LIKE '%{$safe_q}%' AND created_at < now() - 300";
$tweets = mysqli_query($db, $query);
confirm_query($tweets);
while ($tweet = mysqli_fetch_assoc($tweets)) {
$created_at = $tweet['created_at'];
$timestamp = strtotime($created_at);
$created_at_no_seconds = date('Y-m-d H:i', $timestamp);
if(!in_array($created_at_no_seconds, $xy_coords)) {
$created_at = $tweet['created_at'];
$timestamp = strtotime($created_at);
$created_at_no_seconds = date('Y-m-d H:i', $timestamp);
if(!in_array($created_at_no_seconds, $xy_coords)) {
$xy_coords = array(0 => $created_at_no_seconds, array('tweet_count' => $tweet_count, 'retweets' => 0));
} else {
// $created_at_no_seconds exists in array
// update array
$msg_vol[$created_at_no_seconds] = array('tweet_count' => $tweet_count++, 'retweets' => 0);
}
}
return $msg_vol;
I'm reformatting the $created_at to the minute as, for the time being, I'm only interested in the data for the last 5 minutes (300 seconds) and want each minute separated out into it's own associative array. The $created_at_no_seconds variable can potentially contain duplicate entries to be added in the array. So, I've toyed with in_array() to try and check if it exists and only add it to the array if it does not. I didn't have much luck with this yet.
A print_r($msg_vol) provides the following output (which is slowly getting closer to the desired output):
[0] => Array
(
[created_at] => 2013-12-15 19:09
[tweet_count] => 1
[retweets] => 0
)
[2013-12-15 19:09] => Array
(
[tweet_count] => 11
[retweets] => 0
)
[1] => Array
(
[created_at] => 2013-12-15 19:09
[tweet_count] => 1
[retweets] => 0
...
[12] => Array
(
[created_at] => 2013-12-15 19:10
[0] => Array
(
[tweet_count] => 12
[retweets] => 0
)
)
[2013-12-15 19:10] => Array
(
[tweet_count] => 20
[retweets] => 0
)
[13] => Array
(
[created_at] => 2013-12-15 19:10
[0] => Array
(
[tweet_count] => 12
[retweets] => 0
)
)
...
(I'm not processing the retweets at the moment, so I'm simply adding a 0 to the retweets array as a placeholder).
I'm trying to format it so that in one array, it contains the unique date (down to the minute) where the values for tweet_count is stored within it. The above example with the date as the associative key, and the $k => $v inside is what I'm trying to achieve. But, when I keep getting the array populated with [0], [1]. [12], [13], etc.
Am I even close? This has been quite the rabbit hole... And, it's starting to become a dark and lonely place. :(
instead of using array push like this
array_push($msg_vol, $xy_coords);
why not try
$array[] = $xy_coords;
With regards the duplicates why not use SELECT DISTINCT in your mysql query?
I was able to solve the problem by optimizing the query (Thank you #php)!
$query = "SELECT DATE_FORMAT(created_at, '%Y-%d-%m %H:%i'),";
$query .= " COUNT(tweet_id), 0 FROM `tweets`";
$query .= " WHERE tweet_text LIKE '%{$safe_q}%'" ;
$query .= " AND created_at < now() - 300";
$query .= " GROUP BY DATE_FORMAT(created_at, '%Y-%d-%m %H:%i')";
$tweets = mysqli_query($db, $query);
confirm_query($tweets);
while ($tweet = mysqli_fetch_assoc($tweets)) {
echo '<pre>';
print_r($tweet); exit;
echo '</pre>';
}
Make use of MySQL functions. They are a life (and, hair) saver!
Wondering if anyone can help with the following. Basically I have a form which allows users to select a start and end date, start time and end time.
The user can add time blocks, so they select the info they want, post it, then the page is returned, this happens until they process the form with the complete button.
The issue I am facing is, I need my array to append each post to my array, I have the following code:
if($this->input->post('submit', TRUE) == 'more')
{
$start_date = $this->input->post('start_date', TRUE);
$start_time = $this->input->post('start_time', TRUE);
$end_time = $this->input->post('end_time', TRUE);
$start_dates['start_date'] = $start_date;
$start_dates['start_time'] = $start_time;
$start_dates['end_time'] = $end_time;
if(isset($this->session->userdata['start_dates']) )
{
$merged = array_merge_recursive($start_dates, $this->session->userdata['start_dates']);
}
else
{
$merged = null;
$this->session->set_userdata('start_dates', $start_dates);
}
Problem is, each time we add a new time block one of the items in the array is overwritten.
The expected output for the array is:
Array
(
[start_date] => Array
(
[0] => 2012-08-31
[1] => 2012-08-29
)
[start_time] => Array
(
[0] => 08:00
[1] => 09:00
)
[end_time] => Array
(
[0] => 12:00
[1] => 17:00
)
)
Array key [1] is always overwritten in this case, if we add only two time blocks this would not be a problem - however the user needs to be able to add more than 2 blocks, total limit is up to user to a set limit we'll specify later.
Could anyone help get the logic sorted out.
Thanks in advance.
Mark
You need to save the merged data into the session too and the array merge should apply to the stored array in session:
if($this->session->userdata['start_dates'])
{
$merged = array_merge_recursive($this->session->userdata['start_dates'],
$start_dates);
}
else
{
$merged = $start_dates;
}
$this->session->set_userdata('start_dates', $merged);