Thread: Adding to a string date

  1. #1
    Registered User
    Join Date
    Feb 2002
    Posts
    329

    Adding to a string date

    Given the date as a string, how can i achieve this date as a struct tm*?
    I need a datestring as input, then add a variable number of days to this date, and then display the date as a string again.
    I tried the following:
    Code:
    struct tm *ts;
    time_t binDate(0);
    int iDays = 300;
    
    time(&binDate);
    ts=localtime(&binDate);
    ts->tm_year = iYearFromStr;
    ts->tm_mon  = iMonthFromStr;
    ts->tm_mday = iDayFromStr;
    binDate = mktime(ts);//Convert to binary time
    binDate += 86400*iDays;// Add the number of days
    ts = localtime(&binDate );	// Regn tilbake til struct
    Last edited by knutso; 01-20-2004 at 06:00 AM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You're on the right track.
    Just use binDate for incrementing the time in terms of seconds. Then convert the result into a struct tm if need be.
    Code:
    #include <time.h>
    #include <stdio.h>
    
    #define NUM_SECONDS_IN_DAY (60 * 60 * 24)
    
    int main()
    {
        // number of seconds elapsed since midnight (00:00:00), January 1, 1970, UTC
        time_t tval; 
        
        time(&tval);
    
        printf("Current Time: %s\n", ctime(&tval));
    
        // add 5 days to tval
        tval += NUM_SECONDS_IN_DAY * 5;
    
        printf("5 Days Later: %s\n", ctime(&tval));
    
        return 0;
    }//main
    gg

  3. #3
    Registered User
    Join Date
    Feb 2002
    Posts
    329
    Thanks for the reply. I just figured it out myself as well:
    Code:
    struct tm *ts;
    time_t binDate(0);
    int iDays = 300;
    
    time(&binDate);
    ts=localtime(&binDate);
    ts->tm_year = iYearFromStr+100;//!!!!After 2000 you have to add 100 to year
    ts->tm_mon  = iMonthFromStr;
    ts->tm_mday = iDayFromStr;
    binDate = mktime(ts);//Convert to binary time
    binDate += 86400*iDays;// Add the number of days
    ts = localtime(&binDate );	// Back to structformat
    ts->tm_year-=100;
    printf("DDMMYY:%02i%02i%02i",ts->tm_mday,ts->tm_mon,ts->tm_year );

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    You're both assuming that time_t stores seconds

    Use mktime() to normalise a time value, like so
    Code:
    #include <stdio.h>
    #include <time.h>
    
    int main(void) {
      struct tm ts;
      time_t now, later;
      int iDays = 300;
    
      time(&now);
      printf( "Now = %s", asctime(localtime(&now)));
      ts = *localtime(&now);
      ts.tm_mday += iDays;      // some time from now
      later = mktime( &ts );    // Convert to binary time
      printf( "Later = %s", asctime(localtime(&later)));
      return 0;
    }
    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
    Join Date
    Feb 2002
    Posts
    329
    I implemented a function for this:
    Code:
    /*************************************************\
     * dateAdd()                                     *
     * Adds a given number of days to a string date  *
     * Input:                                        *
     *	ts      ->Timestruct, not allocated, hence** *
     *	achDate ->Datebuffer in format CCYY.MM.DD		 *
     *	iAdd    ->Number of days to add       			 *
     * Output:                                       *
     *	void                                         *
    \*************************************************/
    void dateAdd(struct tm **ts, char *achDate, int iAdd){
      time_t tBuf(0);
    	char achBuf[3];
    
    	// Init vars
    	achBuf[2]=0;
    	time(&tBuf);
    	*ts=localtime(&tBuf);
    	// Fetch date from string
    	memcpy(achBuf, achDate+2, 2); (*ts)->tm_year = atoi(achBuf);
    	memcpy(achBuf, achDate+5, 2); (*ts)->tm_mon  = atoi(achBuf);
    	memcpy(achBuf, achDate+8, 2); (*ts)->tm_mday = atoi(achBuf);
    	// Calculate new date
    	(*ts)->tm_year += 100;
    	tBuf = mktime(*ts);			// Convert to binary time
    	tBuf += 86400*iAdd;			// Add number of days
    	*ts = localtime(&tBuf);	// Update time struct
    	(*ts)->tm_year -= 100;	// I only want a two digit year
    }

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> You're both assuming that time_t stores seconds
    time() returns a value in seconds - no need to assume.

    gg

  7. #7
    Registered User
    Join Date
    Feb 2002
    Posts
    329
    So the case is closed. Thank's for the assistance.

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >> You're both assuming that time_t stores seconds
    >time() returns a value in seconds - no need to assume.

    http://groups.google.com/groups?hl=e...ws.net&rnum=18
    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.*

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I think that link is somewhat mis-leading Dave. I don't think a time_t with those properties would be allowed.

    From reading n869 (and from K&R-II), time_t is an arithmetic type which at least suggests that you should be able to do
    if ( t1 < t2 )

    That is, you could call time() at different points in the program and be able to estabish a 'before' relationship without the need to check the sign of a difftime() call.

    What the ANSI-C standard does not say about time_t are
    - what the underlying data type is (int, long, double)
    - the epoch time (typically 1/1/1970)
    - the resolution (typically seconds)
    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 Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    It's strange that the IEEE Std 1003.1, 2003 Edition (my link above) says that the resolution is in seconds from the Epoch.
    One of the differences between the ISO and ANSI standard perhaps?

    However, to use the strategy I posted earlier, you would have to account for leap year seconds - so Salem's and knutso's method is much easier anyways.

    I've never used these functions so this is what I did to prove it to myself.
    Code:
    #include <time.h>
    #include <stdio.h>
    
    time_t seconds_between_years(int y1, int y2)
    {
        struct tm tm1={0}, tm2={0};
    
        tm1.tm_year = y1 - 1900;
        tm2.tm_year = y2 - 1900;
    
        time_t t1 = mktime(&tm1);
        time_t t2 = mktime(&tm2);
    
        return (t1 > t2) ? (t1 - t2) : (t2 - t1);
    }//seconds_between_years
    
    int main()
    {
        int year;
        for (year = 1990; year < 2004; year++)
        {
            printf("%d - %d = %d seconds\n", 
                   year + 1, year,
                   seconds_between_years(year, year + 1));
        }//for
        
        return 0;
    }//main
    gg

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >I don't think a time_t with those properties would be allowed.

    >you should be able to do
    >if ( t1 < t2 )

    I didn't go through all of this, but early on it at least suggested that this might not necessarily be so. (Then again, parsing comp.std.c for useful information is definitely not my strong suit.)


    I'm not trying to argue in favor of whatever bizarre implementation might exist. I just threw the previous link out there as some example of an unusual scenario that could possibly(?) exist... I thought I was continuing your argument to use the time functions.
    Last edited by Dave_Sinkula; 01-20-2004 at 04:34 PM.
    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
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >From reading n869 (and from K&R-II), time_t is an arithmetic type which at least suggests that you should be able to do
    >if ( t1 < t2 )
    Iffy. time_t must be an arithmetic type because sometimes values of type time_t have to be compared with -1. However, the standard says nothing about the arithmetic properties of time_t aside from that, so while t1 < t2 will probably work, the result isn't guaranteed to be portable. That's the whole reason difftime was introduced by the standards committee, to allow programmers to find the difference of two times while still allowing the implementation to choose the best format possible for representing time_t.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A Lil Help With Inheritance...
    By frassunit in forum C++ Programming
    Replies: 16
    Last Post: 03-04-2009, 03:54 AM
  2. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  3. RicBot
    By John_ in forum C++ Programming
    Replies: 8
    Last Post: 06-13-2006, 06:52 PM
  4. Adding Scores from a string array
    By MB1 in forum C++ Programming
    Replies: 6
    Last Post: 11-11-2005, 07:27 AM
  5. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM