Начинающие школяры начинают тут же вручную изобретать календарь: массив {31, 28, 31, ...}, високосные годы и т.д. - так как они сами его представляют и в меру своей осведомлённости...
Но задача здесь не в изобретении календаря, а в том, чтобы сделать это всё используя исключительно стандартный POSIX API для даты/время!
Код: Выделить всё
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
time_t normalize( struct tm *date ) {
time_t t = mktime( date );
*date = *localtime( &t );
return t;
}
int main( int argc, char **argv ) {
if( argc != 3 ) printf( "число параметров\n" ), exit( 1 );
struct tm date[ 2 ] = { {}, {} };
time_t t[ 2 ];
for( int i = 0; i < 2; i++ ) {
int num = 0;
char *token = strtok( argv[ i + 1 ], "." );
while( token != 0 ) {
if( 0 == atoi( token ) ) printf( "формат даты\n" ), exit( 1 );
switch( num++ ) {
case 0: date[ i ].tm_mday = atoi( token ); break;
case 1: date[ i ].tm_mon = atoi( token ) - 1; break;
case 2: date[ i ].tm_year = atoi( token ) - 1900; break;
default: printf( "формат даты\n" ), exit( 1 );
}
token = strtok( NULL, "." );
}
if( num != 3 ) printf( "формат даты\n" ), exit( 1 );
t[ i ] = normalize( date + i );
printf( "%s дата:\t%s", i ? "конечная" : "начальная", asctime( &date[ i ] ) );
}
if( t[ 1 ] < t[ 0 ] ) printf( "последовательность дат\n" ), exit( 1 );
unsigned day = 0;
while( date[ 0 ].tm_year < date[ 1 ].tm_year ) {
struct tm last = {
.tm_mday = 31, .tm_mon = 11, .tm_year = date[ 0 ].tm_year
};
normalize( &last );
day += last.tm_yday - date[ 0 ].tm_yday + 1;
date[ 0 ].tm_mday = 1; date[ 0 ].tm_mon = 0; date[ 0 ].tm_year = date[ 0 ].tm_year + 1;
normalize( date );
} // пока годы различаются
day += date[ 1 ].tm_yday - date[ 0 ].tm_yday;
printf( "между ними дней: %d\n", day );
return 0;
}
Код: Выделить всё
$ ./difd 01.01.2015 01.01.2016
начальная дата: Thu Jan 1 00:00:00 2015
конечная дата: Fri Jan 1 00:00:00 2016
между ними дней: 365
$ ./difd 01.01.2016 01.01.2017
начальная дата: Fri Jan 1 00:00:00 2016
конечная дата: Sun Jan 1 00:00:00 2017
между ними дней: 366
$ ./difd 01.01.2000 01.01.2001
начальная дата: Sat Jan 1 00:00:00 2000
конечная дата: Mon Jan 1 00:00:00 2001
между ними дней: 366
$ ./difd 01.01.1900 01.01.1901
начальная дата: Mon Jan 1 00:00:00 1900
конечная дата: Tue Jan 1 00:00:00 1901
между ними дней: 365