Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Questions about datetime usage

Status
Not open for further replies.

KempCGDR

Programmer
Jan 10, 2003
445
GB
Hi, I'm writing an online game and I need to know the last time the user was playing so the game can allocate extra turns/health. Basically I want it to work as below:

1) At end of each page there is a statement setting a field in that user's record in my user table to the current date and time, that field is defined as a datetime field at the mo.

2) When a page loads, it checks the stuff saved above and if it is a new day (3 game days to one normal day = 8 hours each), then they get allocated extra turns to use and some health is regenerated.

Basically, I have no experience whatsoever using dates and times in php, so I need help. I've probably missed out loads of stuff you need to know to help me, so anything you need, just ask.
 
The first thing one would need to know is how and where you're storing the time in your user table.

Is it a CSV file or a database, if a database, which one?

Second thing you should probably do is read the family of functions relating to time and date in PHP.

I'd say start here

and read all the functions that pop up on the left side of the screen.

If you just use a format from there, and save that as a text field in your database, you'll be good enough.

If you want to be efficient and you're using mySQL read about dates in mySQL and find quickly how easy this will be for you.

-Rob
 
yeah, I'm using mySQL. I'll check out the functions and see if I can make sense of them.
 
I can safely say that none of that made any sense to me.

The last date and time the user accessed a page is stored in a field called laston in a table called rpg_user and is defined as a datetime field (format is yyyy-mm-dd hh:mm:ss as far as I know).

I assume setting it will be a simple case of something like:

"UPDATE rpg_user SET laston=now() WHERE name='$username'"



After I've retrieved it at the start of a page, I need to check how many new 8 hour game days the user has entered since he/she was last on, eg.

I leave the game at 15:00 one day and go back on 19:00 the next day. Days start at 00:00, 8:00 and 16:00. This means I need extra stuff from 4 days (the one starting an hour after I left, the one at midnight, the one starting at 8 the next morning and the one starting 3 hours before I logged back on). Is there an easy way to do this, taking in to account that it won't neccessarily be on the same day etc?
 
Ok, so you've set it as a date time in mySQL...

(I don't have the ability to be testing this stuff right now, so if you don't mind I'm just going to think through it with you... if you do mind say so and we can wait for someone who just knows)

Now setup a simple script which just retrieves that record...

SELECT laston FROM rpg_user WHERE name='myName';
(yes, hardcode one just for testing)

Now print that data out and see what you get...

I don't think it's actually in that format you suggested, but it may be... it may be instead in the form of a timestamp, I wish I knew.

But give it a try, report back here with the output, and then we'll know which PHP function to use to turn it into a format you can do something with.

-Rob
 
I get

0000-00-00 00:00:00

which is the default contents, hence my assumption that it was yyyy-mm-dd hh:mm:ss.

Does that help?
 
Indeed it helps... personally I'd prefer a straight timestamp, but hey what can you do.

unfortunately I'm not sure if PHP treats that as something special or as a string... have you tried comparing two of them?

have you tried applying the strtotime() function to it to see if it generates a valid timestamp?

once you get it into a timestamp it's easy... just subtract the two, and divide by the number of seconds in 8 hours (28800)... that's how many game days have passed.

I'd try strtotime() and see what comes back.

-Rob


You

 
So it would be easier if I use a timestamp? How would I stick the current time/date into it in a mySQL query?

As to the dividing by eight, I assume there would be some kind of rounding involved, obviously I don't need to know fractions of a game day.

The problem I can see with that divide by eight is that it won't neccessarily pick up changes. For instance, I view one page at 7:30 and one at 8:30, it won't pick that one up. If it does pick that up, then your style of method will also pick up 5:30 - 6:30, which isn't a new day. My guess is I need a loop of some kind, but the defined times thing is going to be really annoying.
 
Oh, you have defined "midnights" and those are all that count?

That's going to be some more clever math then...

dividing by eight is only going to give the # of days (fractions included or not at your whim)... and then you're going to need to compare absolute times...

How to do this...

midnight is going to equal what, 0,8,16 hours each day right?

So.... (sorry just thinking as I type)...

This is how I'd approach it...

Take your last_on timestamp, apply the date and time functions to determine how many hours have passed since 0:00:00 that day.

if it's 0-7 you have 0 midnights passed
If it's 8-15 you have 1 midnight passed
if it's 16-23 you have 2 midnights passed

then do the same to your now on timestamp


then figure the number of real days which have passed.

The total # of midnights is
The number of midnights passed on the now_on time stamp
plus the number of real days passed * 3
minus the number of midnights passed on the last_on time stamp

-Rob
 
If you want to know the number of whole 8-hour periods that have elapsed between the current datetime and the last time the user logged in, something like:

Code:
select
	thetime,
	floor(((unix_timestamp(now()) - unix_timestamp(thetime))-((unix_timestamp(now()) - unix_timestamp(thetime)) % 28800))/28800)
from bar

Assuming that the last login is in a column named "thetime"

Want the best answers? Ask the best questions: TANSTAAFL!
 
sleipnir... apparently that's not enough though... he needs to know if a specific time was crossed.

i.e.
thetime = 7:30
now = 8:30
1 unit elapsed

thetime = 6:30
now = 7:30
0 units elapsed

But it looks like sleipnir came in with the mySQL functions which I was hoping existed for the timestamp conversions... should be easy from there.

-Rob
 
Ok, solution thought of. How about having a timestamp for midnight on some random day in the past and then when they load a page it calculates how many eight hour chunks have passed since then and takes away the number of chunks that passed since they last viewed a page, drop any decimals and there you have the number that have passed.

Only problem is I have no idea how to implement any of this, and your posts confused me more than I started off.

Just realised how little I know about php programming. :(
 
The code I posted was actually a complex MySQL SQL query. No action would be taken on the PHP side. But skiflyer is right -- my query would only tell you the number of times a 8-hour period could be subtracted from the intervening time between the last login and now.

But my code implements the complementary function of the modulus ("%") operator. Modulus will tell you the remainder after one number is subtracted as many times as possible from another. What you need to know is not the remainder, but the actual number of times the first number could be subtracted from the second. Although PHP does not have this, something like floor ($a / $b) will do it.

You can do a lot in PHP by performing calculations on unix-timestamp seconds counts.

Pick your game start real time, and convert that to a unix timestamp. Something like strtotime($the time) is a way to do it.

Then query the time of the last login. Convert that to a unix timestamp, then subtract gamestart form the last login. Store that in $result. Perform floor(($result / 28800). This will give you the number whole 8-hour periods that happened between the two.

Get the current time, and perform the same operations on it. By comparing the two, you will know the exact number of 8-hour windows, as counted from the beginning of the game, that have occurred since the last login. Want the best answers? Ask the best questions: TANSTAAFL!
 
Ok, I came up with something that I thought would work, but it doesn't. I used the timestamp the start of existence (as far as the server is concerned) because that was a midnight.

I have

echo('Time is :'.time().'<br>');

$elapsed = time() - $user['laston']; //Seconds elapsed from last on to now
echo('Time since last page call :'.$elapsed.'<br>');

$days = floor($elapsed / 28800); //Eight hour periods elapsed
echo('Number of days since last page call :'.$days.'<br>');

$query = &quot;UPDATE rpg_user SET laston = now() WHERE name = '$username'&quot;;
mysql_query($query) or die(&quot;Unable to update database!&quot;);

Unfortunatly, the database isn't updated, no error messages or anything, laston just stays as 0.

As far as I know, the variables get the right values, I get

Time is :1048536280
Time since last page call :1048536280
Number of days since last page call :36407

Any obvious mistakes?
 
btw, laston is now an Int field so I can just dump the timestamp in there.
 
Sorry, it was a logic error. There was nothing in $username, that's why it worked up to there.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top