Thread: Calculate time left...

  1. #1
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194

    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;
    }
    "Artificial Intelligence usually beats natural stupidity."

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    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 %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?
    Last edited by IndioDoido; 05-20-2007 at 02:11 PM.
    "Artificial Intelligence usually beats natural stupidity."

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well now you would do difftime(now,result);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    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
    "Artificial Intelligence usually beats natural stupidity."

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    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
    Last edited by zacs7; 05-21-2007 at 01:48 AM.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    58
    A day is (60 ^ 2) * 24

    There are 24 hours not 60 :P

  8. #8
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    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?
    "Artificial Intelligence usually beats natural stupidity."

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Having calculated a forward date using mktime(), you can format that however you want with strftime()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    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, "%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" );
    }
    Sorry about this, but i'm realy new in programing
    "Artificial Intelligence usually beats natural stupidity."

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    too complex for me

    anyway, i'm going to give it some more looks...
    "Artificial Intelligence usually beats natural stupidity."

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by IndioDoido View Post
    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.

    [edit]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]
    Quote Originally Posted by IndioDoido View Post
    anyway, i'm going to give it some more looks...
    Please do.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    Registered User IndioDoido's Avatar
    Join Date
    Apr 2007
    Posts
    194
    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?
    "Artificial Intelligence usually beats natural stupidity."

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by IndioDoido View Post
    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);
        printf("Your subscription began %s\n", buffer);
        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.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sending an email in C program
    By Moony in forum C Programming
    Replies: 28
    Last Post: 10-19-2006, 10:42 AM
  2. Time between Military Hours
    By StarOrbs in forum C++ Programming
    Replies: 18
    Last Post: 03-01-2005, 06:46 PM
  3. pointer to array of objects of struct
    By undisputed007 in forum C++ Programming
    Replies: 12
    Last Post: 03-02-2004, 04:49 AM
  4. Killing someones grandparents
    By nickname_changed in forum A Brief History of Cprogramming.com
    Replies: 37
    Last Post: 09-07-2003, 07:56 AM
  5. The Timing is incorret
    By Drew in forum C++ Programming
    Replies: 5
    Last Post: 08-28-2003, 04:57 PM