1. ## Calculate time left...

Hi,

I'm trying to create a function that calculates the days left to the end of a subscription.

Example:
I have a function that registers a user in a program, and stores the subscription date in a structure.
Now, I want to create a function that calculates the days left for the end of his subsription.

SUBSCRIPTION DATE: 20-05-2007
SUBSCRIPTION ENDS IN: 30 DAYS
...
...
...
SUBSCRIPTION DATE: 20-05-2007
SUBSCRIPTION ENDS IN: 22 DAYS

I don't have any ideia on getting this to work

Can anyone help me on this?

Code:
```typedef struct
{
int day, month, year;
}Date;

Date actualDate()
{
Date h;
time_t a;
struct tm* b;
time (&a);
b=localtime(&a);
h.day = b->tm_mday;
h.month = b->tm_mon+1;
h.year = b->tm_year+1900;
return h;
}```

2. Use mktime() to construct a time_t value for the end of the subscription.

Use difftime() to work out how much time remains between now and later.

3. hi Salem...

i've found this mktime() function on the VS2005 help, but i don't know how to stor the returning date in a struct, so that i can use (i think) the difftime()

Code:
```int newDate(int num_days)
{
struct tm when;
__time64_t now, result;

_time64( &now );
when = *_localtime64( &now );
printf( "Current time is &#37;s\n", asctime( &when ) );

when.tm_mday = when.tm_mday + days;
if( (result = _mktime64( &when )) != (time_t)-1 )
printf( "In %d days the time will be %s\n",
days, asctime( &when ) );
else
perror( "_mktime64 failed" );
}```
Can you help me on this?

4. Well now you would do difftime(now,result);

5. hey!

yes, i know

but i would like to stor the date of the end of subscription in a struct, so that every time i run the program it can compare the actual date with the end of subscription date.

I use this to get the actual date, and stor it in a struct as the register date.
Now i need a similar function to calculate the date of the end of subscription, to stor in the same struct.

Code:
```typedef struct
{
int day, month, year;
}Date;

Date actualDate()
{
Date h;
time_t a;
struct tm* b;
time (&a);
b=localtime(&a);
h.day = b->tm_mday;
h.month = b->tm_mon+1;
h.year = b->tm_year+1900;
return h;
}```
I need this because in my project I need this info for each user:

REGISTER DATE: 20-05-2007
END OF SUBSCRIPTION: 20-06-2007
DAYS LEFT: 30

6. Why not work with / store the timestamp?

A UNIX timestamp is in seconds (since the UNIX epoch), so a minute is 60 seconds, an hour 60^2 seconds, a day 60^3 seconds.

So, pseudo code wise
Code:
```day = pow(60, 3);
mystamp = mystamp + (2 * day)```
Will add a 2 days to the timestamp

7. A day is (60 ^ 2) * 24

There are 24 hours not 60 :P

8. hey guys!

My first problem is that i want to store the end of subscription date in this format: 21-05-2007 (day-month-year) in a struct.

And then, only then use that date format to calculate te days left from the register day to the end of subscription date.

Exmp.:
REGISTER DAY: 21-05-2007
END OF SUBSCRIPTION DAY: 21-06-2007
YOU HAVE 30 DAYS LEFT...
Any ideias?

9. Having calculated a forward date using mktime(), you can format that however you want with strftime()

10. hey Salem!

i'm using this code to format my actual date:
Code:
```main ();
{
char dateActual_dmA[11];
/*char dateFinal_dmA[11];*/
struct tm *date;

time_t a;
time(&a);

date = localtime(&a);
strftime(dateActual_dmA, 11, "&#37;d-%m-%Y", date);

printf("Date_dmY: [%s]\n",dateActual_dmA);

/*difftime(dateActual_dmA, char dateFinal_dmA*/
}```
how can i use this _mktime() function with the one above?
Code:
```dateFinal(void)
{
struct tm when;
__time64_t now, result;
int    days;

_time64( &now );
when = *_localtime64( &now );
printf( "Current time is %s\n", asctime( &when ) );
days = 30;
when.tm_mday = when.tm_mday + days;

result = _mktime64(&when);
asctime (&when);

difftime(
if( (result = _mktime64( &when )) != (time_t)-1 )
{
printf( "In %d days the time will be %s\n", days, asctime( &when ) );
}
else
perror( "_mktime64 failed" );
}```

11. too complex for me

anyway, i'm going to give it some more looks...

12. Originally Posted by IndioDoido
too complex for me
If you strip out the error checking, which is a bad idea, you'd have this.
Code:
```const char *dtstamp(int days, const char *format)
{
static char result [ 80 ];
time_t t;
struct tm *local;
/*
* Try to obtain the implementation's best approximation to the current
* calendar time.
*/
time ( &t );
/*
* Try to convert the calendar time pointed into a broken-down time.
*/
local = localtime ( &t );
/*
* It might be prudent to check for integer over/underflow here, but I'll
* live dangerously and just adjust by the offset.
*/
local->tm_mday += days;
/*
* Try to convert the adjusted broken-down time into a calendar time value.
*/
t = mktime ( local );
/*
* Try to convert the adjusted calendar time pointed into a broken-down time.
*/
local = localtime ( &t );
/*
* Try to create a formatted output string.
*/
strftime ( result, sizeof result, format, local );
return result;
}```
If you take out the comments, you'd then have this.
Code:
```const char *dtstamp(int days, const char *format)
{
static char result [ 80 ];
time_t t;
struct tm *local;
time ( &t );
local = localtime ( &t );
local->tm_mday += days;
t = mktime ( local );
local = localtime ( &t );
strftime ( result, sizeof result, format, local );
return result;
}```
This is not a helluvalot different from what you already have.

If you really cut the use of space, you may even whittle it to this.
Code:
```const char *dtstamp(int days, const char *format)
{
static char result [ 80 ];
time_t t = time ( NULL );
struct tm *local = localtime ( &t );
local->tm_mday += days;
t = mktime ( local );
local = localtime ( &t );
strftime ( result, sizeof result, format, local );
return result;
}```
But these are generally all steps backwards from the original.[/edit]
Originally Posted by IndioDoido
anyway, i'm going to give it some more looks...

13. hey Dave!

yap, it's not that complex, as i said before :P sorry...

i changed your code so that the function returns the days left from the actual time and the later date, but it gives me a stupid value...so that means i'm doing somethig stupid...
Code:
```#include <stdio.h>
#include <time.h>

const int *dtstamp(int days, const char *format)
{
int days_left = 0;
static char result [ 80 ];
time_t t = time ( NULL );
struct tm *local = localtime ( &t );
local->tm_mday += days;
t = mktime ( local );
local = localtime ( &t );
strftime ( result, sizeof result, format, local );

days_left = difftime(local, result);

return days_left;
}

main()
{
printf("%d", dtstamp(30, "%d-%m-%Y") );
}```
...right?

14. Originally Posted by IndioDoido
hey Dave!

yap, it's not that complex, as i said before :P sorry...
Good, then hopefully this won't be either. This is just my concept of your problem. I hope the comments are actually useful to you.
Code:
```#include <stdio.h>
#include <time.h>

int main(void)
{
char buffer[BUFSIZ];
double diff;
time_t begin, end, now;
struct tm *local, stop, start = {0};
/*
* Obtain start date. Here I'll fake it (May 10, 2007).
*/
start.tm_year = 2007 - 1900;
start.tm_mon  = 5 - 1;
start.tm_mday = 10;
/*
* Make this into a "real" time.
*/
begin = mktime(&start);
if ( begin == (time_t)-1 )
{
return 0;
}
/*
* Then localize it.
*/
local = localtime(&begin);
if ( !local )
{
return 0;
}
start = *local; /* start is now normalized and localized */
/*
* This far we've just been dealing with the start date. The normalization
* and localization is to get things in their proper ranges and such. That
* is, no such thing as May 119th, for example.
*
* Now we get to pretty much repeat the process with the end date.
*/
stop = start; /* a copy of the start */
stop.tm_mday += 30; /* add 30 days */
/*
* Now normalize the end date.
*/
end = mktime(&stop);
if ( end == (time_t)-1 )
{
return 0;
}
/*
* And let's find out the current date and time.
*/
now = time(NULL);
if ( now == (time_t)-1 )
{
return 0;
}
/*
* All righty, let's find out how much time in seconds is between now and
* the end.
*/
diff = difftime(end, now);
/*
* Then convert seconds into days, and then lop off the fraction.
*/
diff /= 60 * 60 * 24;
diff = (int)diff;
printf("diff = &#37;g\n", diff); /* only for demonstration purposes, remove */
/*
* But let's dress this up a bit. Let's localize the end.
*/
local = localtime(&end);
if ( !local )
{
return 0;
}
/*
* And bear with me, let's localize the current time as well.
*/
local = localtime(&now);
if ( !local )
{
return 0;
}
/*
* Now we can use strftime on both the start and the end to make nice
* messages.
*/
strftime(buffer, sizeof buffer, "%A %B %d, %Y", &start);
strftime(buffer, sizeof buffer, "%A %B %d, %Y", &stop);
printf("Your subscription will end %s\n", buffer);
strftime(buffer, sizeof buffer, "%A %B %d, %Y", local);
printf("Today is %s. You have %g days remaining.\n", buffer, diff);
/*
* And we're done!
*/
return 0;
}

/* my output
diff = 17
Your subscription began Thursday May 10, 2007
Your subscription will end Saturday June 09, 2007
Today is Tuesday May 22, 2007. You have 17 days remaining.
*/```
There's just a kind of general pattern of back-and-forth between struct tm's and timet_t's. Other than that tediousness, it's not as bad as it looks. While not terribly simple to understand at first, working with date and time using the standard library isn't that tough. (Other than being tough to look at.)

I think now you ought to be able to put together the code you are trying to develop. Post your latest attempts if you still have questions.