I have looked everywhere for a simple answer to this but I have not been able to find a solution that either works or meets my requirements.
I am looping through data, that looks similar to this:
Array
(
[0] => 4c36fd909b37208b
[1] => event:
[2] => start_scan
[3] => 2012-08-17 12:01:15
)
Array
(
[0] => 4c36fd909b37208b
[1] => sysaction:
[2] => lower_device
[3] => 2012-08-17 12:01:19
)
Array
(
[0] => 4c36fd909b37208b
[1] => event:
[2] => how_to_use_displayed
[3] => 2012-08-17 12:01:46
)
Array
(
[0] => 4c36fd909b37208b
[1] => event:
[2] => scan_displayed
[3] => 2012-08-17 12:01:59
)
Array
(
[0] => 4c36fd909b37208b
[1] => sysaction:
[2] => layer_1_display_on_recognition
[3] => 2012-08-17 12:02:23
)
I want to work out the time between two dates and the result needs to be in the format HH:MM:SS.
In the example data above, I need the difference between 2012-08-17 12:01:15 and 2012-08-17 12:02:23, which should be 00:01:08.
I have tried to use the code from here: http://www.if-not-true-then-false.com/2010/php-calculate-real-differences-between-two-dates-or-timestamps/ but it keeps returning 00:00:20
I have also tried this (where the date in the first array is saved as $xpTime and the date in the last array is set to $xpEndTimeTmp):
$start = new DateTime($xpTime);
$end = new DateTime($xpEndTimeTmp);
$diff = $start->diff($end);
$xpDuration = date('H:i:s', strtotime($diff->h.':'.$diff->i.':'.$diff->s));
But that seems to be working either (it returns the same hour, minute and a different second).
I hope someone can help me, tell me what I am doing wrong, or has sample code that could that could set me on the right track!
$t1 = '2012-08-17 12:01:15';
$t2 = '2012-08-17 12:02:23';
echo gmdate("H:i:s", strtotime($t2) - strtotime($t1));
Result
00:01:08
This version also works when the difference is more than 24 hours:
$start = strtotime('2012-08-17 12:01:15');
$end = strtotime('2012-08-17 12:02:23');
$delta = $end - $start;
$hours = floor($delta / 3600);
$remainder = $delta - $hours * 3600;
$formattedDelta = sprintf('%02d', $hours) . gmdate(':i:s', $remainder);
echo $formattedDelta;
If you only want to know how to calculate the time-difference, there is no need to supply all that code in your question.
A simple: 'I need the difference between 2012-08-17 12:01:15 and 2012-08-18 12:02:23, which should be 24:01:08' would have been much clearer. In this case Janis Elsts' answer beat me to it :)
If however you put the example-code there for a reason, because you also want to know how to get the first and last time, you should look into multi-dimensional array's (combined with a working time-difference routine).
So assuming you have stuffed all your single array's in one wrapping array called $log, you would then do something like:
$timeDiff = strtotime(end($log)[3]) - strtotime(reset($log)[3]);
$hours = floor($timeDiff / 3600);
$remainder = $timeDiff - $hours * 3600;
$formattedTime = sprintf('%02d', $hours) . gmdate(':i:s', $remainder);
echo $formattedTime;
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; }));
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].",";
}
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 order an array of results using a rating forumula I have created, it works by creating a new rating value based on time since posting.
Heres the rating formula: Ratings decrease overtime (Times are in unix timestamps format)
$new_rating = $current_rating / ($current_time - $post_time);
Array
(
[0] => Submissions Object
(
[title] => Exploits Emerge For Linux Privilege Escalation Flaw
[link] => http://test.com
[description] => test description test
[tags] => hardware,government,libya
[rating] => 10
[date] => 1327546314
)
[1] => Submissions Object
(
[title] => High School Students Send Lego Man 24 Kilometers High
[link] => http://test.com
[description] => test description test
[tags] => hardware,government,libya
[rating] => 5
[date] => 1327546305
)
)
My question is how do I sort this array using the above formula? or is their a way I can insert this formula into the mysql query statement?
Thanks a lot everyone.
You're going to want to use usort along with a custom sorting function.
function get_rating($obj)
{
$obj->rating / (time() - $obj->date);
}
function my_compare_func($a, $b)
{
$a = get_rating($a);
$b = get_rating($b);
if($a == $b) return 0;
return ($a > $b)? 1: -1;
}
usort($array_of_objs, 'my_compare_func');
You have to use usort() function.
Something along these lines of using usort should work:
usort($objects, function($a, $b) {
$rating_of_a = $a['rating'] / ($current_time - $a['date']);
$rating_of_b = $b['rating'] / ($current_time - $b['date']);
return ($rating_of_a < $rating_of_b) ? -1 : 1;
});