点击上方“程序人生”,选择“置顶公众号”
第一时间关注程序猿(媛)身边的故事
作者
De掉所有bug
如需转载,请联系原作者授权。
前言:活了那么久,想不想知道自己已经在这个世界上活了多少天了?本文就以小程序的形式解决这个问题,告诫大家人生苦短,请务必惜时如金。
为了提升小程序的用户体验,不让用户做过多的输入,我们引入C语言中的<time.h>这个头文件,让程序自动读取本机时间,用户只需要输入自己的生日,即可获悉自己的存活天数。
首先介绍一下<time.h>的部分用法:
与日期和时间相关的数据结构
#ifndef _TM_DEFINED
struct tm {
int tm_sec; /* 秒 – 取值区间为[0,59] */
int tm_min; /* 分 - 取值区间为[0,59] */
int tm_hour; /* 时 - 取值区间为[0,23] */
int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */
int tm_year; /* 年份,其值等于实际年份减去1900 */
int tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */
int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/
};
#define _TM_DEFINED
#endif
由此可知,tm是一个结构体,里面的一系列成员即是与本机时间相关的参数。需要注意的是,tm_year并不是实际的公元纪年,tm_year+1900才是实际的公元纪年,tm_mon也不是实际的月份,tm_mon+1才是实际的月份。例如,今天是2018年8月13日,tm_year的实际值是118,tm_mon的实际值是7。
下面我们尝试打印一下本机时间,里面的部分代码是获取本机时间的固定形式。
#include <stdio.h>
#include <time.h>
int main()
{
struct tm *local;
time_t t;
t=time(NULL);
local=localtime(&t);
printf("现在的时间是:%d年%d月%d日%d时%d分%d秒\n",local->tm_year+1900,local->tm_mon+1,local->tm_mday,local->tm_hour,local->tm_min,local->tm_sec);
return 0;
}
下面进入核心算法部分:
整个小程序虽然只有一行输入和一行输入,里面设计的内容却复杂的很。需要涉及闰年的问题,(year%4==0&&year%100!=0||year%400==0)为真的即为闰年,闰年的2月有29天。
上代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Date
{
int year;
int month;
int day;
}date;
void main()
{
int i;
int T;
int dert_year=0;
int dert=0;
//x[0]为生日 x[1]为本机时间
date x[2];
//获取本机时间
struct tm *local;
time_t t;
t=time(NULL);
local=localtime(&t);
x[1].year=local->tm_year+1900;
x[1].month=local->tm_mon+1;
x[1].day=local->tm_mday;
//正常年份12个月的天数
int months_normal[12]={31,28,31,30,31,30,31,31,30,31,30,31};
//闰年12个月的天数
int months_run[12]={31,29,31,30,31,30,31,31,30,31,30,31};
//输入
printf("请输入您的生日:");
scanf("%d%d%d",&x[0].year,&x[0].month,&x[0].day);
//检查输入 只是粗略检查 并没有考虑具体月份的情况
if(!(x[0].month>=1&&x[0].month<=12&&x[0].day>=1&&x[0].day<=31))
{
printf("您的输入有误!\n");
exit(0);
}
/************************中间天数****************************/
if(x[0].year<x[1].year)
{
dert_year=x[1].year-(x[0].year+1);
T=x[0].year;
for(i=0;i<dert_year;i++)
{
if((T+1)%4==0&&(T+1)%100!=0||(T+1)%400==0)
dert+=366;
else
dert+=365;
T++;
}
/************************后向天数****************************/
if(x[1].year%4==0&&x[1].year%100!=0||x[1].year%400==0)
for(i=0;i<x[1].month;i++)
{
dert+=months_run[i];
}
else
for(i=0;i<x[1].month-1;i++)
{
dert+=months_normal[i];
}
dert+=x[1].day;
/************************前向天数****************************/
if(x[0].year%4==0&&x[0].year%100!=0||x[0].year%400==0)
for(i=x[0].month;i<12;i++)
{
dert+=months_run[i];
}
else
for(i=x[0].month;i<12;i++)
{
dert+=months_normal[i];
}
if(x[0].year%4==0&&x[0].year%100!=0||x[0].year%400==0)
dert+=months_run[x[0].month-1]-x[0].day;
else
dert+=months_normal[x[0].month-1]-x[0].day;
}
else
{
if(x[0].month<x[1].month)
{
if(x[0].year%4==0&&x[0].year%100!=0||x[0].year%400==0)
{
for(i=x[0].month;i<x[1].month-1;i++)
dert+=months_run[i];
}
else
{
for(i=x[0].month;i<x[1].month-1;i++)
dert+=months_normal[i];
dert+=x[1].day;
dert+=months_normal[x[0].month-1]-x[0].day;
}
}
else
dert=x[1].day-x[0].day;
}
//输出结果
printf("您在这个世界上已经活了%d天!\n问问自己,有多少天白活了?\n",dert);
}
为了体现整个思路的流畅性,我几乎将所有的代码都放到了主函数中,请大家见谅。
由上述代码可知,我将天数的计算分成了三部分,一部分是前向天数,一部分是中间天数,一部分是后向天数。所谓的前向天数是指出生日期当年剩余的天数,例如出生日期为1999年6月18日,则前项天数为自1999年6月19日0时起至1999年12月31日24时止的总天数;后向天数是指本机日期当年已经经过的天数;例如本机时间为2018年8月13日,则后向天数为自2018年1月1日0时起至2018年8月13日24时止的总天数。而中间天数是指间隔年的所有天数,举个例子,1998年3月2日和2000年6月18日,间隔年就是1999年这一整年;若是1998年3月2日和1999年6月18日,则没有间隔年,只有前向天数和后向天数。间隔年若为闰年则天数加上366,间隔年若为正常年份则天数加上365。此外,在前向天数和后向天数的计算中,也要注意考虑闰年和正常年份,以及2月这个特殊的月份。
最后为大家展示一下实验结果:
人生不过三万天,你有多少的时间虚度了,又有多少的时间用来敲了代码,又有多少的时间陪了家人和朋友。希望各位程序猿/媛们可以拿出更多的时间做更有意义的事。共勉。
- The End -
「若你有原创文章想与大家分享,欢迎投稿。」
加编辑微信ID,备注#投稿#:
程序 丨 druidlost
小七 丨 duoshangshuang
这里有个免费线上分享会,了解一下
扫描下方海报二维码,添加小助手,回复「分享」,小助手会邀你进群。免费听《神经网络与PyTorch实战》该书作者肖智清的分享。
分享结束后,会在群内抽出5名互动积极用户,免费送出作者著作一本!
上期精彩内容