First all; I'm sorry if my question is not irrelevant. I'm new on array's with PHP.
I have an array;
[
{
"order_id":"7",
"order_start_time":"08:00:00",
"order_end_time":"11:00:00",
"order_date":"29\/03\/2018"
},
{
"order_id":"8",
"order_start_time":"10:00:00",
"order_end_time":"01:00:00",
"order_date":"29\/03\/2018"
}
]
I want to split time ranges from start to end by hours. Desired output;
[
{
"hour_selected":"08:00:00"
},
{
"hour_selected":"09:00:00"
},
{
"hour_selected":"10:00:00"
},
{
"hour_selected":"11:00:00"
},
{
"hour_selected":"12:00:00"
},
{
"hour_selected":"13:00:00"
}
]
But i'm lost how can i do this with time hour ranges.
Any help greatly appricated.
PS: I'm creating array from mysql datetime field.
the simpliest solution is to use unix timestamp:
<?php
$timeFrom = '08:00:00';
$timeTo = '15:00:00';
function rangeBetweenHours($from, $to)
{
$timeFrom = strtotime('today ' . $from);
$timeTo = strtotime('today ' . $to);
$out = [];
foreach (range($timeFrom, $timeTo, 60 * 60) as $timestamp) { // 60 * 60 is a hour
$out[] = date('H:i:s', $timestamp);
}
return $out;
}
var_dump(rangeBetweenHours($timeFrom, $timeTo));
Here you can see working example:
http://sandbox.onlinephpfunctions.com/code/8fec4a2f6b067dc66705732b3c43301cc8722d3f
[
{
"order_id":"7",
"order_start_time":"08:00:00",
"order_end_time":"11:00:00",
"order_date":"29/03/2018"
},
{
"order_id":"8",
"order_start_time":"10:00:00",
"order_end_time":"01:00:00",
"order_date":"29/03/2018"
}
]
Apply for each on this and get order_start_time & order_end_time in an array then sort as per values associating as par increasing order of time.
Related
I have a JSON source and I am trying to loop trough it and show some results (up to 9 results) which is not a problem
The problem is that I want to show only the results that are matching a certain date, where the date might be exact or between 2 dates.
For example I want to show only the events where let say the date 2019-11-17 is within timeFrom timeTo of the event or timeFrom or timeTo is equal to it. In that example it will be event 1 and 3
This is the source sample
{
"title":"event 1",
"timeFrom":"2019-11-16 19:00:00",
"timeTo":"2019-11-18 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
},
{
"title":"event 2",
"timeFrom":"2019-11-20 19:00:00",
"timeTo":"2019-11-20 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
},
{
"title":"event 3",
"timeFrom":"2019-11-17 19:00:00",
"timeTo":"2019-11-17 22:00:00",
"listText":"text of the event",
"url":"https://url",
"imageUrl":"https://image.jpg",
"locations":{
"title":"Location name",
"url":"https://location"
}
And this is the foreach I have at the moment
foreach(array_slice($arr, 0, 9) as $data) {
//then I will show the result
}
So, I can't figure out how to make that condition within the foreach.
This function iterates through the events data, looking for events whose from and to dates surround the given date:
function find_events($events, $date) {
$date = new DateTime($date);
foreach ($events as $event) {
$from = (new DateTime($event['timeFrom']))->setTime(0,0,0);
$to = (new DateTime($event['timeTo']))->setTime(0,0,0);
if ($date >= $from && $date <= $to) {
echo "{$event['title']} ({$event['listText']}) from {$event['timeFrom']} to {$event['timeTo']}\n";
}
}
}
$events = json_decode($json, true);
find_events($events, '2019-11-17');
Output:
event 1 (text of the event) from 2019-11-16 19:00:00 to 2019-11-18 22:00:00
event 3 (text of the event) from 2019-11-17 19:00:00 to 2019-11-17 22:00:00
Demo on 3v4l.org
Try this code:
$date = "2019-11-17";
$events = json_decode($json_output, true);
foreach ($events as $event)
{
if (($date > $event['timeFrom'] && $date < $event['timeTo']) || in_array($date, array($event['timeFrom'], $event['timeTo'])))
{
$filtered_events[] = $event;
}
}
$sliced_events = array_slice($filtered_events, 0, 9);
print_r($sliced_events);
How to calculate a date before 10 days of every month end ?Am using codeigniter platform.
I need to check whether a date is within 10 days before the end of every month.
Please help
You can try using date_modify function for example see this php documentation
http://php.net/manual/en/datetime.modify.php
i need to check whether a date is within10 days before the end of a month
function testDate($date) {
$uDate = strtotime($date);
return date("m", $uDate) != date("m", strtotime("+10 days", $uDate));
}
echo testDate("2016-03-07") ? "Yes" :"No"; // No
echo testDate("2016-03-27") ? "Yes" :"No"; // Yes
you can create a library with this
class Calculate_days{
function __construct() {
parent::__construct();
}
function calculate( $to_day = date("j") ){
$days_month = date("t");
$result = (int) $days_month - $to_day;
if( $result <= 10){
$result = array("type" => TRUE, "missing" => $result . 'days');
return $result;
}
else{
$result = array("type" => FASLE, "missing" => $result . 'days');
return $result;
}
}
}
controller.php
function do_somthing(){
$this->load->library('Calculate_days');
$result = $this->Calculate_days->calculate(date("j"));
var_dump($result);
}
Hello i got a JSON response that looks like the one below. I want to count the posts that are younger then 24 hours and also check for unique user urls:
{
"meta":{
"network":"all",
"query_type":"realtime"
},
"posts":[
{
"network":"facebook",
"posted":"2014-08-16 08:31:31 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Terance Podolski",
"url":"someURL",
"image":"someURL"
}
},
{
"network":"facebook",
"posted":"2014-08-16 08:30:44 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Łukasz Podolski",
"url":"someURL",
"image":"someURL"
}
},
{
"network":"facebook",
"posted":"2014-08-16 08:25:39 +00000",
"sentiment":"neutral",
"url":"someURL",
"user":{
"name":"Marcin Podolski",
"url":"someURL",
"image":"someURL"
}
}
]
}
Thanks in advance.
With the help of #Elias Van Ootegem i got my problem solved. The code looks like that:
// Json Reponse decodieren
$jsonArray = json_decode($jsonData);
function getMentionsFromLast24H($myArray){
// set variable exactly one day ago
$since = new DateTime('-1 day');
// array where to store timestamps in
$recent = array();
foreach ( $myArray -> posts as $post ) {
try {
$post -> posted = new DateTime (substr ( $post->posted,0,19 ) );//create DateTime instance
if ( $post -> posted >= $since )
$recent[] = $post;//add to array
} catch ( Exception $e ) {
echo $e -> getMessage();
exit(1);
}
}
return $recent;
}
$mentions24h = count(getMentionsFromLast24H($jsonArray));
print_r($mentions24h);
It's pretty simple, really: decode the json data, compare the posted values with time - 24 hours, if the value is great than time-24 hours, add it to an array. That's it, you'll end up with an array containing all posts that were added in the last 24 hours:
$data = json_decode($jsonData);//creates object
$since = new DateTime('yesterday');
$recent = array();//this is the array we'll be constructing
foreach ($data->posts as $post)
{
$post->posted = new DateTime($post->posted);//create DateTime instance
if ($post->posted > $since)
$recent[] = $post;//add to array
}
var_dump($recent);//this is the array you're after
That really is all there is to it.
i want to equal youtube playlist all videos time from this link http://gdata.youtube.com/feeds/api/playlists/PLCK7NnIZXn7gGU5wDy9iKOK6T2fwtGL6l. here have time code like this time='00:05:11.500' .. i want to get all videos time from php then its show like this from php
show it like this : 2:10:50 (2=hours,10=minutes,50=seconds)
i want to variable from php for like this one. plzz help for this post thanks. i tried to do that.. but i can do this.. if someone can plz help me.. if have 4 videos, want to equal all videos time and then want to show all duration from php only
Ok, here's an answer that solves the problem assuming you have no code whatsoever, and no intention of
trying do experiment yourself.
You will probably not be able to use this for anything else than the exact problem described:
adding all the durations of this feed together and displaying it as hours:minutes:seconds
<?php
$total_seconds = 0;
$dom = new DOMDocument();
$dom->loadXML(file_get_contents('http://gdata.youtube.com/feeds/api/playlists/PLCK7NnIZXn7gGU5wDy9iKOK6T2fwtGL6l'));
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//yt:duration/#seconds') as $duration) {
$total_seconds += (int) $duration->value;
}
Then you display $total_seconds in your format. Here's two options:
assuming that hours will never be larger than 24
echo gmdate("H:i:s", $total_seconds);
allowing total time to be larger than 24 hours
echo (int) ($total_seconds / 3600) . ':' . (int) ($total_seconds / 60) % 60 . ':' . $total_seconds % 60;
Keep in mind: This code does exactly ZERO error checking. Things that can go wrong:
The PHP configuration may not allow http stream wrapper
The PHP build might not have Dom enabled
The XML feed may be unavailable
The XML feed might not contain any entries
EDIT:
I took a closer look at the feed, and it seems the "time" entries are just pointers for the thumbnails. The actual duration for a video is set in seconds <yt:duration seconds='667'/> so you could just add them together as integers and then use the DateTime class to convert to whatever your format is. Example here.
END EDIT
First of all, to get all the times, you could need an atom feed reader in PHP. There are plenty out there. Do not try to parse the XML, ATOM is a well known standard that should be easily used (if you really only want the times, you could go with an xpath query).
Now that you have all the times at your disposal, you need a way to add them up easily, preferably without messing with nested loops and if-statements.
Here's a class that represents a single time entry for a single video:
final class Duration
{
private $hours;
private $minutes;
private $seconds;
private $centis;
/* we don't want any Durations not created with a create function */
private function __construct() {}
public static function fromString($input = '00:00:00.000') {
$values = self::valuesFromString($input);
return self::fromValues($values['hours'], $values['minutes'], $values['seconds'], $values['centis']);
}
public function addString($string) {
$duration = self::fromString($string);
return $this->addDuration($duration);
}
public function addDuration(Duration $duration) {
// add the durations, and return a new duration;
$values = self::valuesFromString((string) $duration);
// adding logic here
$centis = $values['centis'] + $this->centis;
$this->fixValue($centis, 1000, $values['seconds']);
$seconds = $values['seconds'] + $this->seconds;
$this->fixValue($seconds, 60, $values['minutes']);
$minutes = $values['minutes'] + $this->minutes;
$this->fixValue($minutes, 60, $values['hours']);
$hours = $values['hours'] + $this->hours;
return self::fromValues($hours, $minutes, $seconds, $centis);
}
public function __toString() {
return str_pad($this->hours,2,'0',STR_PAD_LEFT) . ':'
. str_pad($this->minutes,2,'0',STR_PAD_LEFT) . ':'
. str_pad($this->seconds,2,'0',STR_PAD_LEFT) . '.'
. str_pad($this->centis,3,'0',STR_PAD_LEFT);
}
public function toValues() {
return self::valuesFromString($this);
}
private static function valuesFromString($input) {
if (1 !== preg_match('/(?<hours>[0-9]{2}):(?<minutes>([0-5]{1}[0-9]{1})):(?<seconds>[0-5]{1}[0-9]{1}).(?<centis>[0-9]{3})/', $input, $matches)) {
throw new InvalidArgumentException('Invalid input string (should be 01:00:00.000): ' . $input);
}
return array(
'hours' => (int) $matches['hours'],
'minutes' => (int) $matches['minutes'],
'seconds' => (int) $matches['seconds'],
'centis' => (int) $matches['centis']
);
}
private static function fromValues($hours = 0, $minutes = 0, $seconds = 0, $centis = 0) {
$duration = new Duration();
$duration->hours = $hours;
$duration->minutes = $minutes;
$duration->seconds = $seconds;
$duration->centis = $centis;
return $duration;
}
private function fixValue(&$input, $max, &$nextUp) {
if ($input >= $max) {
$input -= $max;
$nextUp += 1;
}
}
}
You can create a new Duration only by calling the static factory fromString(), and that accepts only strings in the form "00:00:00.000" (hours:minutes:seconds.milliseconds):
$duration = Duration::fromString('00:04:16.250');
Next, you can add another string or an actual duration object, to create a new Duration:
$newDuration = $duration->addString('00:04:16.250');
$newDuration = $duration->addDuration($duration);
The Duration object will output it's own duration string in the format '00:00:00.000':
echo $duration;
// Gives
00:04:16.250
Or, if you're interested in the separate values, you can get them like so:
print_r($duration->toValues());
// Gives
Array
(
[hours] => 0
[minutes] => 4
[seconds] => 16
[milliseconds] => 250
)
Final example for using this in a loop to get the total video time:
$allTimes = array(
'00:30:05:250',
'01:24:38:250',
'00:07:01:750'
);
$d = Duration::fromString();
foreach ($allTimes as $time) {
$d = $d->addString($time);
}
echo $d . "\n";
print_r($d->toValues());
// Gives
02:01:45.250
Array
(
[hours] => 2
[minutes] => 1
[seconds] => 45
[milliseconds] => 250
)
For questions on why I used a final class with private constructor:
I wrote this as an exercise for myself, following Mathias Veraes's blog post on "named constructors".
Also, I couldn't resist adding his "TestFrameworkInATweet" as well:
function it($m,$p){echo ($p?'✔︎':'✘')." It $m\n"; if(!$p){$GLOBALS['f']=1;}}function done(){if(#$GLOBALS['f'])die(1);}
function throws($exp,Closure $cb){try{$cb();}catch(Exception $e){return $e instanceof $exp;}return false;}
it('should be an empty duration from string', Duration::fromString() == '00:00:00.000');
it('should throw an exception with invalid input string', throws("InvalidArgumentException", function () { Duration::fromString('invalid'); }));
it('should throw an exception with invalid seconds input string', throws("InvalidArgumentException", function () { Duration::fromString('00:00:61:000'); }));
it('should throw an exception with invalid minutes input string', throws("InvalidArgumentException", function () { Duration::fromString('00:61:00:000'); }));
it('should add milliseconds to seconds', Duration::fromString('00:00:00.999')->addString('00:00:00.002') == Duration::fromString('00:00:01.001'));
it('should add seconds to minutes', Duration::fromString('00:00:59.000')->addString('00:00:02.000') == Duration::fromString('00:01:01.000'));
it('should add minutes to hours', Duration::fromString('00:59:00.000')->addString('00:02:00.000') == Duration::fromString('01:01:00.000'));
it('should add all levels up', Duration::fromString('00:59:59.999')->addString('00:01:01.002') == Duration::fromString('01:01:01.001'));
$duration = Duration::fromString('00:00:01.500');
it('should add a Duration', $duration->addDuration($duration) == '00:00:03.000');
I would like to use a Timer in php, sending messages after a certain period of time (no player activity)? This is for a multi-player game through sockets.
I have googled and stackoverflew and found the following
could use a cron (will need to
synronize my php classes (socket
based) with the cron... ), No I
guess.
could use sleep ... if it could wait
for less than one second, I will have
given a try, No again, I guess
could use register_tick_function ...
not applicable I think
Any ideas?
Thanks!
This is what I wrote to deal with my timing needs. It doesn't magically interrupt your code, but it provides a very flexible way to schedule timers. All you have to do, is make sure you run $events->CheckTimers() every now and then.
The libevent module does a lot more, but that's a bit more effort.
$events = new Events();
function callback($text) {
printf("I'm a timer callback %s\n", $text);
}
$events->AddTimer("5s", "callback", "every 5 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("2s..15s", "callback", "random time 2 to 15 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("1m", create_function('', "echo 'Im a LAMBDA function that runs every minute\n';"), false, EVENTS::EVENT_REPEAT);
$events->AddTimer("1h..2h", "callback", "I will run once, in between 1 and 2 hours");
# This is just an example, in reality, you would make sure to call CheckTimer() regulary (ideally not more than once a second)
while (true) {
$events->CheckTimers();
printf("Next timer in %s seconds...\n", $ne = $events->GetNextTimer(), gettype($ne));
sleep(1);
}
class Events {
const EVENT_REPEAT = 0x0001;
const EVENT_SEQUENCE = 0x0002;
var $events;
var $timers;
function __construct() {
$this->events = array();
$this->timers = array();
}
function AddTimer($when, $action, $args = false, $flags = 0) {
if (preg_match('#([0-9a-zA-Z]+)..([0-9a-zA-Z]+)#', $when, $a)) {
$time = time(NULL) + rand($this->time2seconds($a[1]), $this->time2seconds($a[2]));
} else {
$time = time(NULL) + $this->time2seconds($when);
}
if ($flags & self::EVENT_SEQUENCE) {
while ($this->IsArrayCount($this->timers[$time])) {
$time ++;
}
}
$this->timers[$time][] = array("when" => $when, "action" => $action, "args" => $args, "flags" => $flags);
ksort($this->timers);
}
function GetNextTimer() {
if (!$this->IsArrayCount($this->timers)) {
return false;
}
reset($this->timers);
$firstevent = each($this->timers);
if ($firstevent === false) {
return false;
}
$time = $firstevent["key"];
$nextEvent = $time - time(NULL);
if ($nextEvent < 1) {
return 1;
}
return $nextEvent;
}
function CheckTimers() {
$rv = false;
$now = time(NULL);
foreach ($this->timers as $time => $events) {
if ($time > $now) {
break;
}
foreach ($events as $key => $event) {
# debug("Event::CheckTimer: {$event["action"]}");
# ircPubMsg("Event::CheckTimer: {$event["action"]}", "#bots");
if (!$event["args"]) {
call_user_func($event["action"]);
} else {
$rv = call_user_func_array($event["action"], is_array($event["args"]) ? $event["args"] : array($event["args"]));
}
unset($this->timers[$time][$key]);
if ($event["flags"] & self::EVENT_REPEAT) {
$this->AddTimer($event["when"], $event["action"], $event["args"], $event["flags"]);
}
if ($rv) {
# break;
}
}
if (!$this->IsArrayCount($this->timers[$time])) {
unset($this->timers[$time]);
}
if (0 && $rv) {
break;
}
}
if ($rv) {
return $rv;
}
}
function time2seconds($timeString) {
$end = substr($timeString, strlen($timeString) - 1);
$seconds = intval($timeString); // = preg_replace("#[^0-9]#", "", $a);
if (is_numeric($end)) {
return $seconds;
}
$unim = array("s","m","h","d", "w", "m", "y");
$divs = array(1, 60, 60, 24, 7, 28, 12, false);
$found = false;
while (!$found) {
$u = array_shift($unim);
$d = array_shift($divs);
$seconds *= $d;
if ($end === $u) {
return $seconds;
}
}
return intval($timeString);
}
function IsArrayCount($possibleArray) {
return (isset($possibleArray) && is_array($possibleArray)) ? count($possibleArray) : false;
}
}
Does PHP's time_nanosleep() work for you? Or usleep()?
Maybe a daemon?
http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/
here are a few concepts how to do it :
1. common concept is to create script for sending messages, then add it to server Cron application and execute the script with specified time.
2. write python script that will control your php application file or section, in pythonic terms you can fork process on server start that will do your tasks every amount of time (with infinity loop I guess ... while 1: ..)
3. write shell .sh file that will invoke php or python script and add controls of this script it to /etc/init.d to be more controllable.