`
zhengliweb
  • 浏览: 771 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

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-01
typedef int cal_l;

const char *week_str[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

//both [0] and [12] mean December.  [1]-January, [2]-February, ...
const int month_days[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

// return 0-6 --> week_str[0-6]
int 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 year
int isleap ( int y )
{
    return ( y % 400 == 0 ) || ( ( y % 4 == 0 ) && ( y % 100 != 0 ) ) ;
}

// cal_m to cal_l
cal_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[i];
    }
    days += ( cm->c_day - 1 );
    return days;
}

//cal_l to cal_m
struct 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[2] += isleap ( cm.c_year );
    for ( i = 1; i <= 12 && cl >= month_days[i]; i++ )
    {
        cl -= month_days[i];
    }
    month_days[2] -= isleap ( cm.c_year );
    cm.c_mon = i;
    
    cm.c_day = cl + 1;
    
    return cm;
}

// demo: print  how many days between birthday and today
void 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[cal_week ( cm0.c_year, cm0.c_mon, cm0.c_day )] );
    fprintf ( stdout, "%.4i-%.2i-%.2i, %s\n", cm1.c_year, cm1.c_mon, cm1.c_day, 
             week_str[cal_week ( cm1.c_year, cm1.c_mon, cm1.c_day )] );
    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 [1900.01.01 - 2100.12.31]
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[2] = ( 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[month] )
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

void usage ( void )
{
    fprintf ( stdout, "Usage: <year>,<month>,<day>\n" );
    return;
}

//c main
int 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[BUFSIZ] = {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://zhengliweb.wordpress.com

 

http://zhengliweb.iteye.com

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics