Jump to content
  • Advertisement
Sign in to follow this  
EmpireProductions

C++ Time class

This topic is 3167 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to setup a Time class for doing different things with time. The whole idea is to be able to send a time packet that contains Hour, Minute, Second, Year, Month, and Day from a server to a client. I have the packet being sent from the server to the client with a predefined value for hour and minute. I am then using that to sync the day/night cycle of the client to the "time" on the server. Because I already have the networking end of it done that is not what I need help with. What I need help with is getting the time from the servers computer including the date so it can all be added to the time structure. Here is my class so far including the test stuff I put in. Header:
#include "NetCommon.h"
#include <stdlib.h>
#include <string>

struct RawDateTime;

class MMOTime
{
	
public:
	RawDateTime time2;

	// Time
	bool isHour(int Hour);
	bool isMinute(int Minute);
	bool isSecond(int Second);

	// Date
	bool isMonth(int Month);
	bool isDay(int Day);
	bool isYear(int Year);

	// Helpers
	bool Timer(int Hour, int Minute, int Second);
	int Time();
};
Source
#include "MMOTime.h"
#include <iostream>

// Time
bool MMOTime::isHour(int Hour)
{
	if(time2.Hour == Hour)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool MMOTime::isMinute(int Minute)
{
}

bool MMOTime::isSecond(int Second)
{
}

// Date
bool MMOTime::isYear(int Year)
{
}

bool MMOTime::isMonth(int Month)
{
}

bool MMOTime::isDay(int Day)
{
}

// Helpers
bool MMOTime::Timer(int Hour, int Minute, int Second)
{
}

int MMOTime::Time()
{
	time2.Hour = 7;
	time2.Minute = 22;

	char Hour[5];
	char Minute[5];
	std::string Time;

	itoa(time2.Hour, Hour, 10);
	Time = Hour;

	itoa(time2.Minute, Minute, 10);

	Time = Time + ":" + Minute;

	std::cout << "The Time is: " + Time + "\n";

	return time2.Hour;
}
structure
struct RawDateTime
{
	int Year;
	int Month;
	int Day;
	int Hour;
	int Minute;
	int Second;
};
Any help any one could give me would greatly be welcomed!

Share this post


Link to post
Share on other sites
Advertisement
Any reason why you aren't using tm and its friends, time and asctime? It doesn't have to be just for dealing with real-world time ...

Also, C++ does not have native support for string concatenation, fortunately string streams are type-safe the way to go:


#include <string>
#include <sstream>

std::stringstream ss;
ss << time2.Hour << ':' << time2.Minute << ':' << time2.Second;

// std::cout << "The time is: " + ss.str() + "\n"; // No
std::cout << "The time is: " << ss.str() << '\n';




Or you can provide an overload:

std::ostream& operator << ( std::ostream& out, const RawDateTime& in ) {
out << time2.Hour << ':' << time2.Minute << ':' << time2.Second;
return out;
}

std::cout << "The time is: " << time2 << '\n';


Share this post


Link to post
Share on other sites
Quote:
What I need help with is getting the time from the servers computer


Knowing the time of the system is completely pointless - what good does it for client to know it's quarter past twelve at server's data center, and what if user changes shards and those two have different clocks for whichever reason?

Instead, you will have virtual time which is part of simulation. Decide on a unit (second, perhaps minute, or even hour), and then just update that in the simulation. Whenever a client connects, they receive this virtual time and adjust appearance accordingly. A single int should do the job - it can simulate centuries this way without overflowing.

For world state, seconds are almost too low granularity - it's unlikely that anything would be updated at that rate.

But still, if you choose seconds, simply count the number of seconds that passed since whatever you consider time zero in your world. This also allows you adjust time as needed, regardless of physical time, and it can be persisted if needed.

Another reason for this type of tracking - imagine there is some timed element (24 hour buff). If world time is tied to real time, and server goes down for maintenance, players will lose time. If it's simulation-based, then it's ticking only when the server is running.

Share this post


Link to post
Share on other sites
I want the Day/night cycles to be real time based on the servers time. Thats the way the engine is being designed. For time based quests I will do it differently so its only going when the server is running but for the Environment stuff this is how I want it!

Share this post


Link to post
Share on other sites
Quote:
Original post by EmpireProductions
I want the Day/night cycles to be real time based on the servers time. Thats the way the engine is being designed. For time based quests I will do it differently so its only going when the server is running but for the Environment stuff this is how I want it!


Still - where is the problem? Read the time, send that long. It's exactly the same thing, except that instead of using virtual counter, you read the system time.

Share this post


Link to post
Share on other sites
Quote:
Original post by EmpireProductions
The problem is is that I have never worked with time with C++ before so I don't know how to read the system time.


Ah - fastcall's links answer that.

Share this post


Link to post
Share on other sites
Ok could some one please tell me what is wrong with this code?


bool MMOTime::isSecond(int Second)
{
SYSTEMTIME mSecond;
GetLocalTime(&mSecond);
int lastsecond;

int check;

while(mSecond.wSecond == Second && check == 1)
{
check = 0;
return true;
}
check = 1;

return false;
}


It never returns true for some reason. Is it because I am declaring check in the method so it is being erased each time?

Share this post


Link to post
Share on other sites
Quite simply, check hasn't been initialized when you use it. Depending on which compiler you're using, check could start out as 0, or on MSVC, check could be any random garbage. When check is zero, the condition is never met.


bool MMOTime::isSecond(int Second)
{
SYSTEMTIME mSecond;
GetLocalTime(&mSecond);

// And this is probably what you wanted in one line:
return mSecond.wSecond == Second;
/*
int lastsecond;

// Uninitialized variable:
// int check;
int check = 1;

while(mSecond.wSecond == Second && check == 1)
{
check = 0;
return true;
}
check = 1;

return false; */

}




For future reference, if you have a debugger, learn how to use it and step through the code with a fine-tooth comb.

Share this post


Link to post
Share on other sites
Thanks! I got it working now.

The way you suggested with only using one line works but it doesn't work for what I need. In stead of only returning true once it returns true a whole bunch of times while the statement is true. The way I have it it only returns true once.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!