My problem is this: My game day is supposed to be 1/6 of a real world day. A game day has 12 game hours. Thus one game hour is 20 minutes real time. Or that's what it's supposed to be. However, when I've observed the time, instead of an hour being 20 minutes, it's in fact 30 minutes. I can't figure out what's causing this. What's wrong with my function?
public function getGameTime() {
$t = time();
$d = $t/60/60/6 - 68646;//the number taken off makes the current time day 200 instead of a really big number
$fraction = $d - floor($d);
if ($fraction<(1/12)) $hour = 0;
else if ($fraction<(1/12)*2) $hour = 1;
else if ($fraction<(1/12)*3) $hour = 2;
else if ($fraction<(1/12)*4) $hour = 3;
else if ($fraction<(1/12)*5) $hour = 4;
else if ($fraction<(1/12)*6) $hour = 5;
else if ($fraction<(1/12)*7) $hour = 6;
else if ($fraction<(1/12)*8) $hour = 7;
else if ($fraction<(1/12)*9) $hour = 8;
else if ($fraction<(1/12)*10) $hour = 9;
else if ($fraction<(1/12)*11) $hour = 10;
else $hour = 11;
for ($minute = 59; $minute>=0; $minute--) {
if ((($hour*60+$minute)/720)<$fraction) {
$min = $minute;
break;
}
}
return array(
"day" => floor($d),
"hour" => $hour,
"minute" => $min
);
}
So yes, if I want 6 four hour periods in a day I need to divide by 4. Dividing by 6 gives me four 6-hour periods instead. Because the divisor is the number of real life hours in a game day, not the number of game days in 24 hours. Problem solved.
Related
I'm looking for a posibility to set minutes to "00" instead of "60". I have following code:
$minute = date('i');
$minutesround = round($minute / 10) * 10;
$hour = date('H');
$minutesround = str_pad($minutesround, 2, 0, STR_PAD_LEFT);
$time = $hour . $minutesround;
echo $time;
My problem: If it is eg. 4:56pm the output should like this: 1700
but in my case, I get this 1660
Someone has an idea, how to realize this?
Thank you!
This works well:
$myRoundedTime = round(time()/600) * 600; // round time to nearest 6th of an hour
$time = date('Hi', $myRoundedTime);
echo $time;
A working example: http://sandbox.onlinephpfunctions.com/code/b2b595683d9adf8e5273cbdef775bf69b6c036d4
A simple if statement should do the trick
$hour = date('H');
if($minutesround == 60) {
$minutesround = 0;
$hour++;
if($hour == 24) $hour = '00';
}
I have a website where users enter data including hours, for example they enter '1:00' (Meaning = 1 hour) and '00:15' (Meaning = 15 minutes) and '2:30' (Meaning = 2 hour and 30 minutes).
Now I need to make show them how many hours they have entered in total, when I calculate it by just doing $count += $time in a loop I am getting the correct number but not what is standing after the ':'.
1:00 + 00:15 + 2:30 will become '3' while it should be 3:45.
How would I do this? Also now that I am thinking about it, I will also need if it goes over 60 it adds 1 to the first number (A new hour).
Thanks.
First, calculates minutes, then calculate how many hours are those minutes and add them to the hours:
<?php foreach ($data as $entry) {
list($hour, $minutes) = explode(':', $entry);
$total_hours += $hour;
$total_minutes += $minutes;
}
$hours_from_minutes = floor($total_minutes / 60);
$total_hours += $hours_from_minutes;
$total_minutes -= $hours_from_minutes * 60;
echo "$total_hours:$total_minutes"
A simple solution that supports everything varying from 00:00:00 to just 00:00 and 00
$times = ['00:15', '01:00:13', '24:43:12', '00:00:34'];
$total_seconds = 0;
$total_minutes = 0;
$total_hours = 0;
foreach ($times as $time) {
$array = explode(':', $time);
switch (sizeof($array)) {
case 3:
$total_seconds += (int) $array[2];
case 2:
$total_minutes += (int) $array[1];
case 1:
$total_hours += (int) $array[0];
break;
default:
throw new Exception('got more than expected!');
}
}
$total_minutes += floor($total_seconds / 60);
$total_seconds %= 60;
$total_hours += floor($total_minutes / 60);
$total_minutes %= 60;
printf('%dh %dm %ds', $total_hours, $total_minutes, $total_seconds);
// upd coz strtotime is not for this Q
Try to use DateIntervals, they may help you.
http://php.net/manual/ru/class.dateinterval.php
So here is what I need to do:
Get time from database (don't worry about the database stuff for the moment)
Countdown time in days, hours and minutes
When countdown has reached 0, add 7 days to countdown along with adding 1 to an episode count
repeat multiple times until episode count reaches certain number (set by database, again don't worry to much about the database stuff at the moment) then stop countdown and just echo Aired
Basically its going to countdown to the next episode of a TV show's airing time and show what episode number is next, this will carry on until all the episodes have aired.
Here is what I have currently, it works to a degree but will only +7 days/++episode once, after that the countdown will go into negatives. I've tried while loops and some other things but I haven't had too much luck.
$date = "February 12, 2013 5:06 PM";
$date = strtotime($date);
$remaining = $date - time();
$episode = 0;
if ($remaining < 0) {
++$episode;
$remaining = strtotime("+7 day", $date) -time();
}
$days_remaining = floor($remaining / 86400);
$hours_remaining = floor(($remaining % 86400) / 3600);
$mins_remaining = floor(($remaining % 86400 % 3600) / 60);
if ($episode == 3){
echo "Aired";
} else {
echo "$days_remaining:$hours_remaining:$mins_remaining Ep $episode";
}
Any advice is really appreciated, thanks!
Of course it will go to negative.
After $remaining reaches 0, another 7 days are added to it.
if ($remaining < 0) { // remaining: less than 0 days
++$episode; // episode becomes 1
$remaining = strtotime("+7 day", $date) -time(); // remaining: less than 7 days
}
However, after another 7 days, $remaining is still negative and only 7 days are added to it. Since you haven't saved $episode in a database, it is still 0 according to the code.
$episode = 0; // $episode starts at 0 according to the code
if ($remaining < 0) { // remaining: less than -7 days
++$episode; // episode becomes 1
So it continues to count negative and give you $episode == 1.
You should do this instead:
$date = strtotime("February 12, 2013 5:06 PM");
for ($i = 0; $i < 3; $i++) {
$episodes[$i+1] = strtotime("+". 7*$i ." day", $date);
$remainings[$i+1] = $episodes[$i+1] - time();
}
foreach ($remainings as $key => $remaining) {
if ($remaining > 0) {
$episode = $key;
$days_remaining = floor($remaining / 86400);
$hours_remaining = floor(($remaining % 86400) / 3600);
$mins_remaining = floor(($remaining % 86400 % 3600) / 60);
break;
}
}
if (!isset($episode)){
echo "Aired";
} else {
echo "$days_remaining:$hours_remaining:$mins_remaining Ep $episode";
}
I need to find date x such that it is n working days prior to date y.
I could use something like date("Y-m-d",$def_date." -5 days");, but in that case it wont take into consideration the weekend or off-date. Let's assume my working days would be Monday to Saturday, any idea how I can accomplish this?
Try this
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
return $date;
}
$def_date="";//define your date here
$preDay='5 days';//no of previous days
date_sub($date, date_interval_create_from_date_string($preDay));
echo businessdays($date, $def_date); //date prior to another date
?>
Modified from PHP.net
Thanks for the help guys, but to solve this particular problem I wrote a simple code:
$sh_padding = 5; //No of working days to count backwards
$temp_sh_padding = 1; //A temporary holder
$end_stamp = strtotime(date("Y-m-d", strtotime($date_format)) . " -1 day"); //The date(timestamp) from which to count backwards
$start_stamp = $end_stamp; //start from same as end day
while($temp_sh_padding<$sh_padding)
{
$sh_day = date('w',$start_stamp);
if($sh_day==0){ //Skip if sunday
}
else
{
$temp_sh_padding++;
}
$start_stamp = strtotime(date("Y-m-d",$start_stamp)." -1 day");
}
$sh_st_dte = date("Y-m-d",$start_stamp); //The required start day
A quick bit of googling got me to this page, which includes a function for calculating the number of working days between two dates.
It should be fairly trivial to adjust that concept to suit your needs.
Your problem, however, is that the concept of "working days" being monday to friday is not universal. If your software is only ever being used in-house, then it's okay to make some assumptions, but if it's intended for use by third parties, then you can't assume that they'll have the same working week as you.
In addition, public holidays will throw a big spanner in the works, by removing arbitrary dates from various working weeks throughout the year.
If you want to cater for these, then the only sensible way of doing it is to store the dates of the year in a calendar (ie a big array), and mark them individually as working or non-working days. And if you're going to do that, then you may as well use the same mechanism for weekends too.
The down-side, of course, is that this would need to be kept up-to-date. But for weekends, at least, that would be trivial (loop through the calendar in advance and mark weekend days where date('w')==0 or date('w')==6).
I have a number of days to a date in the future but would like to know how many weeks and days it is. Also, noting that if its less than a week, then it simply returns the same number.
Is this possible?
e.g. 17 days would be 2 weeks and 3 days
e.g. 4 days would be 4 days
I would try something like this:
$days = 17;
$weeks = floor($days / 7);
$dayRemainder = $days % 7;
echo $days.'<br/>'.$weeks.'<br/>'.$dayRemainder;//add whatever logic you need here to get the display the way you want it.
$weeks = intval($days / 7);
$days = $days % 7;
if($weeks)
{
printf("%d weeks", $weeks);
}
if($days)
{
if($weeks)
{
printf(" and ");
}
printf("%d days", $days);
}
Something along the lines of this should work
function getnumweeks(d) {
totalDays = d;
numWeeks = floor(d/7);
if numWeeks != 0 {
extraDays = totalDays % 7;
return array(extraDays, numWeeks);
} else {
return array(totalDays, 0)
}
}
Then you can call and use it as such:
ans = getnumweeks(17)
ans[0] <- Contains number of days
ans[1] <- Contains Number of Weeks
As the Piskvor mentioned, you should use the modulo operator:
$weeks = $days/7;
$daysleft = $days%7;
Let's say x is number of days, W is output value of weeks and D is output value of days remaining.
First do integer division
W = x / 7;
Then you take remainder:
D = x % 7;
$num_days = $databack30[days_to_next_event];
$weeks = floor($num_days/7);
$days = $num_days % 7;
if($weeks>'0'){ $whenitis = ' in '.$weeks.' weeks and '.$days.' days'; }
else { $whenitis = ' in '.$days.' days'; }
I would suggest you to re-use this powerful function datediff:
http://www.addedbytes.com/lab/php-datediff-function/
as suggested in php weeks between 2 dates
or taking inspiration from that code.