TGB/Resources/Real World Time

From TDN

In this resource, I will show you how to extend the code base to return both a formatted time and date, and the real world time that the computer's system clock is currently set to in milliseconds. This is the simplest form I could think of that operates well, that will give enough flexibility to TorqueScript and C/C++ coders.

Before we get started, I am going to warn you. This is a windows implementation only. I do not have access to a linux build setup quite yet, as I am too busy to set one up at the moment, nor do I have any access to a Mac. So all of the file edits inside of winTime.cc should be ported to those platforms. The main edits inside of main.cc should be fine the way they are. If anyone feels like updating this resource, adding in changes for the Mac, or Linux environments, please feel free. I've tried to keep the code to standard posix compatible libraries, so porting should be a breeze. In fact, it should directly port. No windows specific functions are actually used for this resource. I just happen to be coding an a windows machine. I will in the future update this resource, to include the mac and linux ports of this as well, just when I get time.

This was written for version 1.7.5 of T2D/TGB. So, if your not running that version, I make no guarantees about line numbers. The rest should be fine, but let me know if it's not.

Ok, let's start by editing engine/source/platform/platform.h

Find this line in platform.h, should be around line #345

static U32  getTime();

Immediately following that line, add this code

   static char* formatTime(const char* format, U32 time, char* buffer, U32 size);

This is the only function we need to add to platform in order to do what we want to do. Platform already has getTime, which is perfect for our needs. So less work for us, wooHOO! Now in the next file engine/source/platformWin32/winTime.cc, find this function:

U32 Platform::getTime()
{
   time_t long_time;
   time( &long_time );
   return long_time;
}

Should be around line #34. I keep stating around, because I don't know if you are working off of an already modified code base or not. So if not, good, should be line #34. If you are, well, just find the function. Add this code after that function:

char* Platform::formatTime(const char* format, U32 time, char* buffer, U32 size)
{
   time_t now=(time_t)time;
   struct tm *nowTM;
   dMemset(buffer, 0, size);
   nowTM = localtime(&now);
   strftime(buffer, size, format, nowTM);
   
   return buffer;
}

This is the meat of our format function. If this function has an issue processing the time, it should result in a blank buffer / string being returned to you. If it works as expected, you should end up with a formatted string being returned to you. Let me explain this function a little bit for those who aren't as experienced with C/C++. You pass to this function these parameters:

  • the format you want the time returned in,
  • the time data you want formatted,
  • the buffer to store the results in,
  • the length of said buffer.

We are passing a buffer and the length to the buffer in because I'm lazy and don't want to code memory allocation at the moment. So that's up to you. If you want to change this, then by all means please do.

Now, moving on you should open the file engine/source/game/main.cc. Find this block of code in this file:

ConsoleFunction( getRealTime, S32, 1, 1, "() Use the getRealTime function to the computer time in milliseconds.\n"
                                                                 "@return Returns the current real time in milliseconds.\n"
                                                                 "@sa getSimTime")
{
   return Platform::getRealMilliseconds();
}

Should be around line #193.

Add in this code after this console function:

ConsoleFunction( getRealWorldTime, S32, 1, 1, "() Use the getWorldTime function to return the computer's real world clock time in milliseconds.\n"
																"@return Returns the current real world time in milliseconds.\n")
{
   return Platform::getTime();
}

ConsoleFunction( getRealWorldTimeFormat, const char*, 3, 3, "(%format, %time) Use the getWorldTimeFormat function to return a formatted version of %time\n"
																"@return Returns a formatted string of the %time as specified by %format.\n")
{
   //get the current system time
   time_t now=Platform::getTime();   

   //allocate a buffer to send back to the caller, max is 256 bytes.. should be more than enough for a time of any format
   //just don't get carried away with the format string because it will be cut off at 256 bytes.
   char *temp = Con::getReturnBuffer(256);

   //call the new platform format time to format the time in now() according to %format
   return Platform::formatTime(argv[1], dAtoi(argv[2]), temp, 256);
}

Now what we just added here are two console functions. getRealWorldTime and getRealWorldTimeFormat. Here is a brief description of the two functions:

getRealWorldTime() - returns the systems current clock time in milliseconds.
NOTE: This is a UNIX style time value. You can get more information on Unix, or epoch time values here: http://en.wikipedia.org/wiki/Unix_time.

getRealWorldTimeFormat(%format, %time) - Returns a string using the format specified according to the time specified.


Believe it or not, after that you can compile and should have access to these functions in your console and torqueScript.


Here are a few small examples of usage:

Example #1:

%time=getRealWorldTime();
%dateString=getRealWorldTimeFormat("%m/%d/%Y %I:%M:%S %p", %time);
echo ("My real world time is: " @ %dateString);

Example #2:

%dateString=getRealWorldTimeFormat("%m/%d/%Y %I:%M:%S %p", getRealWorldTime());
echo ("My real world time is: " @ %dateString);

Example #3:

echo ("My real world time is: " @ getRealWorldTimeFormat("%m/%d/%Y %I:%M:%S %p", getRealWorldTime()));


The output from any of these should be something like this:

My real world time is: 06/19/2011 03:21:10 PM


Since there is a lot of information about formatting a string, I'll leave it to the other guys to explain how the format string works.

For reference information on the formatting string, please reference these links:
http://msdn.microsoft.com/en-us/library/fe06s4ak%28v=vs.71%29.aspx
http://linux.die.net/man/3/strftime

You can reference almost any C/C++ programming library/book and lookup the function "strftime()". The format specifier for this function is exactly the same. We are just passing the format to strftime inside of the function anyway.