views:

210

answers:

3

I have a program that uses time() and localtime() to set an internal clock, but this needs to be changed so that the internal clock is independent of the user and the "real" time. I need to be able to set any reasonable starting time, and have it count forward depending on a timer internal to the program. Any ideas on the best way to approach this? Here's the excerpt:

#define ConvertToBCD(x) ((x / 10) << 4) | (x % 10);
time_t  tm;
time(&tm);
struct tm *tm_local= localtime(&tm);
tm_local->tm_year %= 100;
tm_local->tm_mon++;
timedata[0] = ConvertToBCD(tm_local->tm_year);
timedata[1] = ConvertToBCD(tm_local->tm_mon);
timedata[2] = ConvertToBCD(tm_local->tm_mday);
timedata[3] =  (tm_local->tm_wday + 6) & 7;
if (!(TimeStatus & 0x02)) tm_local->tm_hour %= 12;
timedata[4] = ((tm_local->tm_hour < 12) ? 0x00 : 0x40) | ConvertToBCD(tm_local->tm_hour);
timedata[5] =  ConvertToBCD(tm_local->tm_min);
timedata[6] =  ConvertToBCD(tm_local->tm_sec);
+1  A: 

A time_t, under POSIX complient systems, is just the number of seconds since the epoch, 1 Jan 1970 0:00:00.

Just add a (possibly negative) value to a time_t to change the time, ensuring that the value doesn't overflow, then use localtime as usual.

tpdi
I concur, store your internal time as an offset to the epoch time.
Chas. Owens
A: 

If you only need whole second resolution, then time() can be used; if you need sub-second resolution, use gettimeofday().

However, if you want to be able to control the values returned, then you will need to define yourself a surrogate for time() (or gettimeofday()). Most libraries are designed along the lines described in Plauger's The Standard C Library, and you can often provide a function called time() that behaves as you want, replacing the standard version. Alternatively, and more safely, you can revise your code to call a function of your own devising, perhaps called simulated_time(), where for production work you can have simulated_time() call the real time() (possibly via an inline function in both C99 and C++) but it can be your own version that schedules time to change as you need.

You don't need to alter your use of localtime(); it simply converts whatever time_t value you give it into a struct tm; you want it to give answers just as it always did.

Jonathan Leffler
A: 

The way I understand it is that you want an internal clock which gets updated according to the progress the real clock makes.

So then you would create something like this:

struct myTime
{
    time_t userStart;
    time_t systemStart;
    time_t curTime;
};

void initTtime(struct myTime *t, time_t time)
{
    t->userStart=time;
    t->systemStart=time(NULL);
}

time_t getTime(struct myTime *t)
{
    t->curTime = t->userStart + time(NULL)-t->systemStart;
    return t->curTime;
}

so using initTime you set the current time you want to have, this gets linked to the system time at that moment in time. When you call getTime using that struct, it updates the starting point with the amount of time progressed. (Note, i haven't tested the code and you can either use the struct directly if you want).

For subsecond precision replace time() and time_t by the gettimeofday equivalent. And for conversion, ascii arting, breakdown to anything else than a second counter you can still use the unix function.

amo-ej1