Timer is counting 1 hour more - php

I'm using a simple way to get a timer from the last action until now, with a cooldown to avoid exploit over a system I am programming.
I am using this formula:
$last_blood = $userRow['lastblood'];
$now_blood = time();
$cooldown_blood = 10800;
$timer_blood = $now_blood - $last_blood;
$next_blood = $cooldown_blood - $timer_blood;
$hours_blood = date("H:i:s", $next_blood);
The thing is that with 60M frame this cooldown system works like a charm, but this time I set it up to 10800 seconds (3 hours).
The $hours_blood keeps stating that I need to wait 1 more hour than the expected.
Results:

Related

How to get the result with these time intervals in php

I'm using a time clock system which, by default, records only the employee's entry and exit times. I'm customizing it so that it's possible to also record break times but I'm having trouble getting the break time to be subtracted from the total time.
This snippet of code is used to register the time between the check-in and check-out:
$time1 = Carbon::createFromFormat("Y-m-d H:i:s", $timeIN);
$time2 = Carbon::createFromFormat("Y-m-d H:i:s", $timeOUT);
$th = $time1->diffInHours($time2);
$tm = floor(($time1->diffInMinutes($time2) - (60 * $th)));
$totalhour = ($th.".".$tm);
The variable ($totalhour) receives the total value between the input register and the output register. It sends to the database in H.i format (hour.minutes), then another page searches for this information in the database and replaces the point (.) with (hr).
Based on this code, I did the same to get the interval start and end timestamps. I was able to get the time between the start time and end time interval with the code below:
$breakstart = table::attendance()->where([['idno', $idno]])->value('breakstart');
$breakend = table::attendance()->where([['idno', $idno]])->value('breakend');
$one = Carbon::createFromFormat("H:i:s", $breakstart);
$two = Carbon::createFromFormat("H:i:s", $breakend);
$breakone = $one->diffInHours($two);
$breaktwo = floor(($one->diffInMinutes($two) - (60 * $breakone)));
$totalbreak = $breakone.".".$breaktwo;
The $totalbreak variable stores the time taken between the start and end of the break. I was also successful in getting the time between this interval.
Now, I need the total time to be done by subtracting the time obtained from the record at the beginning of the interval to the record at the end of the interval.
I did with this code and got good result up to a point. Could you give me tips on how to get an assertive result in this case?
$totalhour = ($th.".".$tm) - ($totalbreak);
I tried to get the total time by subtracting the break time, but without success.

How can I resolve a time() vs microtime() problem?

I am trying to start several processes as close to the same time as possible. A cronjob selects all items to be processed from the database a minute prior to the actual time these processes need to start, and then starts a child process for each record found.
As it can take several seconds to run through the database and spawn the child processes, I am trying to create a sleep or usleep delay so that each spawned child process starts as close as possible to the top of the next minute.
In testing, I have noticed some differences between the child start times returned by time() and microtime().
Here's the code I have to create the delay:
$unixtime_now = time();
$unixMicrotime_now = microtime(true);
$timeToStart = $unixtime_now + 2;
$timeToSleep = $timeToStart - $unixMicrotime_now;
$timeToSleep = number_format($timeToSleep,6);
$timeToSleep = str_replace('.','',$timeToSleep);
usleep ($timeToSleep);
$startedAtMicrotimeFloat = microtime(true);
$startedAtTime = time();
$date1 = date("H:i:s", $startedAtMicrotimeFloat);
$date2 = date("H:i:s", $startedAtTime);
echo "Unixtime Now = $unixtime_now<br />UnixMicroTime Now = $unixMicrotime_now<br />Time to Start = $timeToStart<br />Time to Sleep = $timeToSleep<br />Started at Time = $startedAtTime - $date2<br />Started at MicroTimeFloat = $startedAtMicrotimeFloat - $date1";
Note that I used 2 seconds rather than 60 seconds for the offset to facilitate speed in testing.
2 questions:
1) No matter how many times I run this, the times returned by time() are ALWAYS 1 second before the times returned by microtime(). For example:
Started at Time = 1555765444 - 09:04:04
Started at MicroTimeFloat = 1555765445.0002 - 09:04:05
This is probably a forest for the trees issue, but does anyone have an idea why this is or how I can resolve it?
2) Are there any drawbacks to having a usleep() delay that can be as long as 59 seconds? Would it be better to use sleep() and accept the the child processes might start at 1555765445.9999 - 09:04:05 rather than 1555765445.0002 - 09:04:05, or up to almost a full second later?
Thanks in advance.
Alan
Per Dave's suggestion, I edited the code as follows:
$date1 = date("H:i:s", microtime(true));
$date2 = date("H:i:s", time());
I still get the same result:
Started at Time = 1555876342 - 15:52:22
Started at MicroTimeFloat = 1555876343.0003 - 15:52:23
The microtime() result, which I suspect to be accurate, is later than the time() result by 1.0003 seconds.

How to get the duration of an inserted time by inserting another one with minute:seconds:milliseconds?

I am making a game mode in which I am trying to get the time a player has arrived at their destination after starting the mode and to do this I am using the insert of a date when it starts the mode it inserts a date and after reaching the your destination it registers another date and with both dates it calculates the time it took to get to the destination, with this I'm using date H:i:s (hours, minutes, seconds) but I need to take the time out and leave milliseconds after seconds example: i:s:u (minutes, seconds, milliseconds) but I'm not able to do this, I've tried it in several ways, basically everything works as follows:
1. I add in the player array a current date with hour, minutes, seconds;
$this->game[$player->getName()] = ["start" => strtotime('now')];
2. After the Player arrives at his destination he calculates the time of his trajectory creating another current date with already registered and using date and mktime to do the join and give a visual of time to the player;
$time = date('H:i:s', mktime(0, 0, str_replace("-", "", $this->game[$player->getName()]["start"] - strtotime('now'))));
3. Send the pretty message to the player about the time of his trajectory then time will be something like this: 01:45:23 (minute:seconds:milliseconds).
$player->sendMessage("You beat your time record by ".$time);
This is my method of doing, if you have another better method with the milli seconds added I accept the suggestion! Maybe there might be some errors in my code that I'm still not sure if they work correctly as the subtraction to calculate and join the current time with the previous one, tell me if it's right and if it is not correct correct me or do better. Thank you
Use microtime which returns the current Unix timestamp with microseconds
$game = [];
$game['start'] = microtime(true);
// Do stuff
sleep(3); // Without the sleep, start and end are the 'same'
$game['end'] = microtime(true);
$elapsedTime = ($game['end'] - $game['start']);
$minutes = floor($elapsedTime / 60);
$seconds = $elapsedTime % 60;
$milliseconds = number_format($elapsedTime - floor($elapsedTime),3);

Average sleep interval in PHP

I need to get average sleep interval from following data:
22:00-06:00
00:00-08:00
02:00-10:00
=> expected: 00:00-08:00
22:00-06:00
00:00-08:00
02:00-10:00
04:00-08:00
=> expected: 01:00-08:00
The problem is oscillation around midnight, where part is under 00:00 and part over 00:00.
Simple mean 22+00+02+04 doesn't work. I could count number of times over midnight (3 in this case) and if it's more than those before midnight, I should add 25 co compensate. But this doesn't count with those people, who work at night and go sleep around 8-14!
My theory is: First, somehow I need found peak, something like the most frequented area (e.g., in 9-10 there is 5 record, in 10-11, there is 3 etc.) and then I can decide co compensate border values by adding 24 hours.
What do you think?
What about taking into account relative difference with midnight ?
The result would be (-2+0+2+4)/4 = 00:45
Making the assumption that the person is not sleeping more than 24 hours, then make a method to calculate like so (pseudo code):
calculateSleepTime(sleepTime, wakeupTime) {
if (sleepTime > wakeupTime) {
return (24 - sleepTime) + wakeupTime;
} else {
return wakeupTime - sleepTime;
}
}
averageSleepTime(sleepTimesArray) {
totalSleptTime = 0;
totalTimesSlept = 0;
foreach (oneSleepTime in sleepTimesArray) {
totalTimesSlept++;
totalSleptTime += calculateSleepTime(oneSleepTime);
}
return totalSleptTime / totalTimesSlept;
}
After you get the average sleep time, calculate either the average sleep time, or average wake up time, and do addition/substraction to find your interval. The alternative to this is finding the average sleep time and the average wakeup time (taking relative to midnight times into account).
Determine a lower limit where you can say
Okay, people won't go to sleep this time of the day, if I get this time, it must mean they worked all night and only sleep now
and if the time is below that limit, add 24 hours to both start and finish.

Optimize feed fetching

I'm working on a site now that have to fetch users feeds. But how can I best optimize fetching if I have a database with, lets say, 300 feeds. I'm going to set up a cron-job to which fetches the feeds, but should I do it like 5 every second minute or something?
Any ideas on how to do this the best way in PHP?
If I understand you question, you are basically working on a feed agregator site?
You can do the following; start by refreshing every 1 hor (for example). When you have anough entries from some feed - calculate the average interval between entries. Then use that interval as an interval for fetching that feed.
For example, if the site published 7 articles in the last 7 days - you can fetch feeds from it every 24hours (1day).
I use this algorithm with a few changes, when I calculate this average interval I divide it by 2 (to be sure not to fetch too rarely). If the result is less than 60 minutes - I set the interval to 1h or it is bigger than 24 I set it to 24h.
For example, something like this:
public function updateRefreshInterval() {
$sql = 'select count(*) _count ' .
'from article ' .
'where created>adddate(now(), interval -7 day) and feed_id = ' . (int) $this->getId();
$array = Db::loadArray( $sql );
$count = $array[ '_count' ];
$interval = 7 * 24 * 60 * 60 / ( $count + 1 );
$interval = $interval / 2;
if( $interval < self::MIN_REFRESH_INTERVAL ) {
$interval = self::MIN_REFRESH_INTERVAL;
}
if( $interval > self::MAX_REFRESH_INTERVAL ) {
$interval = self::MAX_REFRESH_INTERVAL;
}
Db::execute( 'update feed set refresh_interval = ' . $interval . ' where id = ' . (int) $this->getId() );
}
The table is 'feed', 'refreshed' is the timestampt when the feed was last time refreshed and 'refresh_interval' is the desired time interval between two fetches of the same feed.
Based on the new information I think I would do something like this:
Let the "first" client initiate the updatework and store timestamp with it.
Everey other clients that will ask for the information get a cashed information until that information are to old. Next hit from a client will then refresh the cashe that then will be used by all clients till next time its to old.
The client that will actually initiate the updatework should not have to wait for it to finnish, just serv the old cashed version and continue to do it till the work is done.
That way you dont have to update anything if no clients are requesting it.
The best thing to do is to be 'nice' and not overload the feeds with lots of needless requests. I settled on a 1 hour update time for one of my webapps that monitors about 150 blogs for updates. I store the time they were last checked in the database and use that to decide when to update them. The feeds were added at random times so they aren't all updated at the same time.
I wrote pfetch to do this for me. It's small, but has a couple really important aspects:
It's written in twisted and can handle massive concurrency even when the network is slow.
It doesn't require any cron jockeying or anything.
I actually wrote it because my cron-based fetchers were becoming a problem. Now I have it configured to fetch some random stuff I want around the internet and then runs scripts whenever things change to update parts of my own web site.

Categories