练手用的,没写注释,很简单的小东西。
本来打算用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
分享到:
相关推荐
输出日历 C语言-打印所有日历-整体打印每个月 很好很强大
C语言课程设计报告--万年历系统设计
c语言写的 万年日历 程序源码
c语言写的CGI 计数器 在linux 下运行的,要自己加一个count.dat的文件,不然会访问失败的。
帅到不行的C语言---简直简单到不行的最简化----约瑟芬报数问题
linux上用c语言写的简易日历,很适合初学者看看.
c语言常用算法-----列举C语言各种常用算法,详尽。对编程大有裨益!
C语言-02-简单数论-整除那套理论.pdf
C语言写的程序很烂-------本资源已关闭!!C语言写的程序-------本资源已关闭!!C语言写的程序-------本资源已关闭!!
纯C语言写的一个小型游戏-源代码.doc
C语言实现神经网络手写数字识别_LeNet-5
C语言教程+C语言100例--学习C语言的经典.chm C语言教程+C语言100例--学习C语言的经典.chm
C语言-文件的操作-2(文件的读写)C-Language-File-Reading-and-Writing-master.zip
算法是这样的,在一个5*5(可自定义)的格子图中,某几个格子中设置有障碍物,算法要求从一个格子出发沿着一个方向前进,不允许走重复交叉的路线,只有碰到不能走的格子才允许转向,要遍历整个图。程序中可定义格子...
30本全部奉献(6):Linux C语言编程一站式学习--pdf完整版
C语言经典经典例子---快速成为C中高手 快速掌握C语言,让你的基础更加牢固
C语言小练习c-language-practice-library-master.zip
C语言实战105例----很多C的源程序,感兴趣的童鞋刻下了研究研究
C语言Turbo-C-2.0-函数中文说明大全.doc