FAQ > Work with dates and times


Match word(s).

If you have any questions or comments,
please visit us on the Forums.

FAQ > How do I... (Level 2) > Work with dates and times

This item was added on: 2003/03/22

C and C++ offer extensive date and time manipulation functions in the <time.h> and <ctime> headers, respectively. The functions that can be used are as follows:


clock_t clock     ( void );
double  difftime  ( time_t time1, time_t time0 );
time_t  mktime    ( struct tm *timeptr );
time_t  time      ( time_t *timer );
char    *asctime  ( const struct tm *timeptr );
char    *ctime    ( const time_t *timer );
struct tm *gmtime ( const time_t *timer );
struct tm *localtime ( const time_t *timer );
size_t strftime ( char *s, size_t maxsize, const char *format,
                  const struct tm *timeptr );


The time header creates four types and two macros for use with these functions:


NULL
CLOCKS_PER_SEC

size_t    /* Result of the sizeof operator */
time_t    /* Represents calendar time */
clock_t   /* Represents CPU execution time */
struct tm /* Holds the components of calendar time */


The clock function measures CPU execution time since the beginning of an implementation defined era related to the program's invocation. To convert the return value of clock to seconds, divide the difference by CLOCKS_PER_SEC:


#include <stdio.h> 
#include <time.h> 

int main ( void )
{
  int i;
  clock_t start, end;

  start = clock();

  for ( i = 0; i < 100000000; i++ )
    ; /* Busy wait, how long doesn't matter */

  end = clock();

  printf ( "The loop took %f seconds\n",
    (double)( end - start ) / (double)CLOCKS_PER_SEC );

  return 0;
}


The time function returns the current date and time as a time_t value. The argument to time can be either NULL, or a pointer to a time_t variable which time will write to. time returns (time_t)-1 on failure.

The difftime() function calculates the interval between two time_t values, returning the difference in seconds.


#include <stdio.h> 
#include <time.h> 

int main ( void )
{
  int i;
  time_t start, end;

  if ( ( start = time ( NULL ) ) != (time_t)-1 ) {

    for ( i = 0; i < 400000000; i++ )
      ; /* Busy wait, how long doesn't matter */

    end = time ( NULL );

    printf ( "The loop took %f seconds\n", difftime ( end, start ) );
  }

  return 0;
}


The tm struct breaks dates and times down into useful components, it's members are:


int tm_sec;   /* seconds after the minute  [0, 60] */
int tm_min;   /* minutes after the hour  [0, 59] */
int tm_hour;  /* hours since midnight  [0, 23] */
int tm_mday;  /* day of the month  [1, 31] */
int tm_mon;   /* months since January  [0, 11] */
int tm_year;  /* years since 1900 */
int tm_wday;  /* days since Sunday  [0, 6] */
int tm_yday;  /* days since January 1  [0, 365] */
int tm_isdst; /* Daylight Saving Time flag */


Two of the functions in the time header convert a time_t value to a tm struct, localtime and gmtime. localtime gives the result represented as the program's local time zone dictates while gmtime returns the result as Coordinated Universal Time (UTC).

Times can be converted to formatted strings with the ctime and asctime functions, the former takes a time_t pointer value as its argument while the latter takes a tm struct pointer. ctime(timer) is equivalent to asctime(localtime(timer)).


#include <stdio.h> 
#include <time.h> 

int main ( void )
{
  time_t now;
  struct tm *tm_now;

  now = time ( NULL );
  tm_now = localtime ( &now );

  printf ( "%s", ctime ( &now ) );
  printf ( "%s", asctime ( tm_now ) );

  return 0;
}


The strftime function performs complex formatting not available to asctime, it is similar to printf in that it takes a format string to determine how the output is to look. The formats are as follows:


%a  /* Abbreviated weekday */
%A  /* Full weekday */
%b  /* Abbreviated month */
%b  /* Full month */
%c  /* Full date and time */
%d  /* Day of the month (1-31) */
%H  /* Hour (24 hour clock) */
%I  /* Hour (12 hour clock) */
%j  /* Day of the year (1-366)*/
%m  /* Month (1-12) */
%M  /* Minute (0-59) */
%p  /* AM/PM for 12 hour clock */
%S  /* Second (0-60) */
%U  /* Week number from Sunday */
%w  /* Weekday (0-6) from Sunday */
%W  /* Week number from Monday */
%x  /* Full date */
%X  /* Full time of day */
%y  /* Year without century */
%Y  /* Year with century */
%Z  /* Time zone */
%%  /* Print a % character */



#include <stdio.h> 
#include <time.h> 

int main ( void )
{
  time_t now;
  struct tm *tm_now;
  char buff[BUFSIZ];

  now = time ( NULL );
  tm_now = localtime ( &now );

  strftime ( buff, sizeof buff, "%A, %x %X %p", tm_now );
  printf ( "%s\n", buff );

  return 0;
}


The mktime function is the opposite of localtime. It takes a tm struct and converts it to a time_t value. If the tm struct can't be represented as a time_t value, (time_t)-1 is returned.

To end this little "How-To", I'll give you a common function that determines if the passed year is a leap year. It doesn't use any of the above functions or types, but it does come in handy when combined with them:


int leap_year ( int year )
{
  return year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 );
}

Credit: Prelude

Script provided by SmartCGIs