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]