Author Topic: Time calculation precision issue  (Read 646 times)

So I'm making a mod that displays the time elapsed since a certain date with the code below using Unix time.
Code: [Select]
function gameConnection::projectTime(%client)
{
//1442523600, 09/17/2015 @ 9:00pm (UTC)
%unix = getUTC()-1442523600;

%years = mfloor(%unix/(60*60*24*365));
%remainder = %unix - %years*60*60*24*365;
%months = mfloor(%remainder/((365/12)*60*60*24));
%remainder = %remainder - %months*(365/12)*60*60*24;
%days = mfloor(%remainder/(24*60*60));
%remainder = %remainder - %days*24*60*60;
%hours = mfloor(%remainder/(60*60));
%remainder = %remainder - %hours*(60*60);
%minutes = mfloor(%remainder/60);
%seconds = %remainder - %minutes*60;

if(strLen(%hours) < 2)
%hours = "0" @ %hours;
if(strLen(%minutes) < 2)
%minutes = "0" @ %minutes;
if(strLen(%seconds) < 2)
%seconds = "0" @ %seconds;

%client.bottomPrint("\c3" @ %years @ "\c0y \c3" @ %months @ "\c0m \c3" @ %days @ "\c0d \c3" @ %hours @ ":" @ %minutes @ ":" @ %seconds);
%client.projtimesched = %client.schedule(1000,"projectTime");
}

The result shows a bottom print which updates every second


It works perfectly except when the time elapsed becomes large - this leads the bottom print to seem to update slower proportionally to the size of %unix, my guess is that the precision of the time calculation is compromised due to having too many bits for Torque to handle... Is there a method I can use to overcome this? Thanks
« Last Edit: November 19, 2015, 05:38:24 AM by General »

Maybe getDateTime() would make this more effective.

I thought the same thing but how would I go about finding the difference between dates in that format?

11/19/15 16:55:15
That's what it returns
09/17/15 19:00:00
That's what you want to subtract.

Subtract the latter from the former checking for overflows.

I don't think  I can check for overflows with the month though, seeing as the days in a month vary?

The impractical, but effective way of solving that is to turn every expression of the form x op y (where op is an operator such as +, -, *, /, etc. but not operators such as &, |, ^, << and >>) into (x op y) | 0. Otherwise, the engine will generally use floating point math and arbitrarily limit the output string to [-]999999 (otherwise converting to scientific notation). For example, instead of x * y + z you can try (((x * y) | 0) + z) | 0 (you can probably omit some of those parens, I don't remember at the moment).
« Last Edit: November 19, 2015, 01:11:52 PM by portify »

Code: [Select]
%old = "09/17/15 19:00:00";
%this = getDateTime();
%do = getSubStr(%this, 6, 8) - getSubStr(%old, 6, 8);
if(%do >= 0)
{
    %endyear = %do;
    %monthoverflow = 0;
}
else
{
    %endyear = 0;
    %monthoverflow = %do * (-1) * 12;
}
...
And you simply apply the monthoverflow in the next calculation and expand this to the rest of the required fields. This is just something I threw together fast in the forum quick reply box. It could be way more nicer and simpler.
« Last Edit: November 20, 2015, 12:27:58 AM by Dannu »