练手用的,没写注释,很简单的小东西。
本来打算用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语言编写的万年历程序。万年历是一种可以显示公历年、月、日以及星期等信息的工具,对于编程爱好者来说,实现一个万年历是一项有趣的挑战,同时也能够提升对日期计算和编程逻辑...
DS1302不仅可以提供小时、分钟、秒的信息,还能存储年、月、日、星期等日期信息,从而实现从1900年到2100年的万年历功能。 - 通过单片机程序,可以实时更新1602液晶屏上的日期和时间显示。 5. **编程语言**: - ...
电子万年历是一种常见的时间显示设备,它能准确地显示当前日期和时间,并且具有足够的存储能力,可以涵盖从公元1900年至公元2100年甚至更远的日期范围。在本项目中,我们将探讨如何使用数码管来显示这样的万年历。 ...
本项目中,我们将深入探讨如何使用51单片机驱动1602液晶显示器来实现一个功能完备的万年历。万年历是一种能够显示当前日期和时间的设备,对于学习单片机编程和硬件接口设计来说,是一个非常实用且有趣的项目。 1. *...
电子万年历是一种能够显示当前日期、时间,并且考虑到闰年规则,可以准确计算直至2100年的日期设备。它在日常生活、工作和学习中发挥着重要作用,尤其在银行、车站、码头、办公室、家庭等场所广泛使用。随着科技的...
1. **`lunarInfo`**: 一个数组,存储了1900年到2100年之间农历月份的信息。 2. **`solarMonth`**: 存储了每个月份的标准天数(不考虑闰月)。 3. **`Gan`**: 天干数组,用于表示天干信息。 4. **`Zhi`**: 地支数组,...
- DS=01: 选择一个二极管。 - DS=10: 选择两个二极管。 - DS=00或11: 即使TCS=1010,充电功能也被禁止。 #### 5. 接口软件及功能应用 - **写保护寄存器操作**: - 通过命令字节8E/8F控制写保护寄存器的状态。 - ...
DS1302 内部集成了一个高精度实时时钟/日历模块和 31 字节的静态 RAM。通过串行接口与外部微处理器进行通信,能够提供秒、分、时、日、月、年等时间信息,并能自动调整每月天数(包括闰年的处理)。此外,该芯片还...
DS1302集成了一款实时时钟/日历和31字节静态RAM,通过简单的串行接口与微处理器进行通信。实时时钟/日历可以提供秒、分、小时、日、日期、月和年等信息,并自动调整每月天数,包括闰年的调整。该芯片在工作电压范围...
万年历时钟是一种能够显示当前日期和时间的装置,它能涵盖从公元1900年到公元2100年的日期范围,甚至更远。在电子领域,万年历时钟通常通过单片机(Microcontroller)进行编程实现,其中C语言是最常见的编程语言之一...
芯片内部有一个实时时钟模块和一个 31 字节的静态 RAM。实时时钟模块负责时间的计数和维护,而静态 RAM 则用于存储用户数据或其他信息。芯片还支持两种不同的工作电压(VCC1 和 VCC2),其中 VCC1 为主电源,而 VCC2...
本文将深入探讨一个基于AT89S52单片机和DS1302实时时钟芯片的电子万年历设计项目,这通常是一个常见的毕业设计课题,旨在培养学生的实践能力和理论知识的综合运用。 AT89S52是一款高性能、低功耗的8位微控制器,...
1. 实时时钟功能强大,可以精确计算从1900年到2100年的秒、分、时、日、日期、星期、月、年,同时具备闰年自动调整功能。 2. 31字节的RAM存储空间,可以用于存储额外的数据或设置。 3. 使用串行I/O接口,只需3个引脚...
DS1302 内置了一个实时时钟 / 日历模块和 31 字节的静态 RAM。它通过简单的串行接口与微处理器进行通信,使得接口设计变得非常简单。实时时钟 / 日历模块提供了秒、分、小时、日期、月份、星期几以及年份的信息。每...
【基于51单片机的时钟】是一个利用51系列单片机实现的数字时钟项目,它具有丰富的功能,如显示时分、月日、年份,并且集成了万年历功能,具备整点报时以及定时自动或手动关闭显示器的特性,以实现空闲模式下的低功耗...
它具有多种功能,包括维护实时时钟(RTC)计数,计数秒、分、时、月中的日、月、星期和年份,还具备闰年补偿功能,此功能一直到2100年都有效。DS1302还包含一个31字节的电池备份非易失性(NV)RAM,用于数据存储。它...
- **实时时钟精度**:具备计算2100年之前的秒、分、时、日、日期、星期、月、年的能力,并能够自动调整闰年。 - **RAM存储容量**:31字节静态RAM。 - **工作电压范围**:宽范围工作电压,2.0V至5.5V。 - **工作电流*...