zhengliweb 发表于 2013-1-26 12:33:57

C写了一个简单的1900-2100日历

练手用的,没写注释,很简单的小东西。

本来打算用C标准库的时间,没能很好理解其中一些细节,放弃了,自己写个玩下。

这应该算是一个demo,用来计算生日还是可以的,计算两个日期差几天。

好吧,上代码,没经过系统测试,喜欢复制去就可以了。
 
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>// calendar struct struct cal_m{    int c_year;    /* years since 1900 */    int c_mon;    int c_day;    };// total days from 1900-01-01typedef int cal_l;const char *week_str[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};//both and mean December.-January, -February, ...const int month_days[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// return 0-6 --> week_strint cal_week ( int y, int m, int d ){    if ( m == 1 || m == 2 )    {      m += 12;      y--;    }    return ( d + 2 * m + 3 * ( m + 1 ) / 5 + y + y / 4 - y / 100 + y / 400 ) % 7;}// is leap yearint isleap ( int y ){    return ( y % 400 == 0 ) || ( ( y % 4 == 0 ) && ( y % 100 != 0 ) ) ;}// cal_m to cal_lcal_l cal_m2l ( struct cal_m *cm ){    int i = 0;    cal_l days = 0;    for ( i = 1901; i <= cm->c_year; ++i )    {      days += 365;      if ( i != cm->c_year )      {            days += isleap ( i );      }    }    if ( cm->c_mon > 2 && isleap ( cm->c_year ) )    {      days += 1;    }    for ( i = 1; i < cm->c_mon; i++ )    {      days += month_days;    }    days += ( cm->c_day - 1 );    return days;}//cal_l to cal_mstruct cal_m cal_l2m ( cal_l cl ){    int i;    struct cal_m cm = {0};    int month_days[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};      for ( i = 1900; cl > ( 365 + isleap ( i ) ); i++ )    {      cl -= 365;      cl -= isleap ( i );    }    cm.c_year = i;      month_days += isleap ( cm.c_year );    for ( i = 1; i <= 12 && cl >= month_days; i++ )    {      cl -= month_days;    }    month_days -= isleap ( cm.c_year );    cm.c_mon = i;      cm.c_day = cl + 1;      return cm;}// demo: printhow many days between birthday and todayvoid cal_diff ( struct cal_m cm0, struct cal_m cm1 ){    int years = 0;    int months = 0;    int days = 0;    cal_l cl0 = 0;    cal_l cl1 = 0;    years = cm1.c_year - cm0.c_year;    if ( cm1.c_mon < cm0.c_mon )    {      years--;    }    else if ( ( cm1.c_mon == cm0.c_mon ) && ( cm1.c_day < cm0.c_day ) )    {      years--;    }    months = ( cm1.c_mon - cm0.c_mon + 12 ) % 12;    if (( cm1.c_day < cm0.c_day ) )    {      months = ( months + 11 ) % 12;    }    days = ( cm1.c_day - cm0.c_day + month_days[ ( cm1.c_mon + 11 ) % 12] )   % month_days[ ( cm1.c_mon + 11 ) % 12];    cl0 = cal_m2l ( &cm0 );    cl1 = cal_m2l ( &cm1 );    fprintf ( stdout, "------------------------------------------------\n" );    fprintf ( stdout, "%.4i-%.2i-%.2i, %s\n", cm0.c_year, cm0.c_mon, cm0.c_day,            week_str );    fprintf ( stdout, "%.4i-%.2i-%.2i, %s\n", cm1.c_year, cm1.c_mon, cm1.c_day,            week_str );    fprintf ( stdout, "\n" );    fprintf ( stdout, "%d days\n", cl1 - cl0 );    fprintf ( stdout, "%d weeks, %d days\n",( cl1 - cl0 ) / 7, ( cl1 - cl0 ) % 7 );    fprintf ( stdout, "%d months, %d days\n", months + years * 12, days );    fprintf ( stdout, "%d years, %d months, %d days\n", years, months, days );    fprintf ( stdout, "%d years, %d months, %d weeks, %d days\n", years, months,            days / 7, days % 7 );    fprintf ( stdout, "------------------------------------------------\n" );    return;}// range int check ( int year, int month, int day ){    int month_days[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};    month_days = ( 28 + isleap ( year ) );    if ( year < 1900 || year > 2100 )    {      return 0;    }    else if ( month < 0 || month > 12 )    {      return 0;    }    else if ( day < 0 || day > 31 )    {      return 0;    }    else if ( day > month_days )    {      return 0;    }    else    {      return 1;    }}void usage ( void ){    fprintf ( stdout, "Usage: <year>,<month>,<day>\n" );    return;}//c mainint main ( int argc, char *argv[] ){    struct cal_m cm0 = {0};    struct cal_m cm1 = {0};    int year0, month0, day0;    int year1, month1, day1;    time_t t_now;    struct tm *tm_now;    char buff = {0};    t_now = time ( NULL );    tm_now = localtime ( &t_now );    year1 = tm_now->tm_year + 1900;    month1 = tm_now->tm_mon + 1;    day1 = tm_now->tm_mday;    cm1.c_year = year1;    cm1.c_mon = month1;    cm1.c_day = day1;    usage();    while ( 1 )    {      fgets ( buff, BUFSIZ, stdin );      year0 = month0 = day0 = 0;      sscanf ( buff, "%d,%d,%d", &year0, &month0, &day0 );      if ( !check ( year0, month0, day0 ) )      {            fprintf ( stderr, "INPUT ERROR! EXIT(-1)\n" );            exit ( -1 );      }      cm0.c_year = year0;      cm0.c_mon = month0;      cm0.c_day = day0;      cal_diff ( cm0, cm1 );    }    return 0;} 
 下面是运行截图,
http://dl.iteye.com/upload/picture/pic/100193/88e820af-8ded-3f87-aee6-bb401e5dd36e.png
 
http://zhengliweb.wordpress.com
 
http://zhengliweb.iteye.com
 
 
页: [1]
查看完整版本: C写了一个简单的1900-2100日历