在我剛開始學(xué)習(xí)編碼的時候渣聚,一個記憶比較深的問題就是時間問題。
根據(jù)“年-月-日”計算這一天是這一年的第幾天僧叉。
當(dāng)時最簡單的方式就是根據(jù)月份值來進行一步步的做加法。
來回味一下當(dāng)時的代碼(當(dāng)時的代碼絕對比這個臭)棺榔,而且當(dāng)時的我是屬于抓狂狀態(tài)的瓶堕。
int day_of_year(int year, int mon, int day)
{
int ret = 0;
int day_of_2m = 28;
if (((0 == year % 4) && (0 != year % 100)) ||
(0 == year % 400))
{
day_of_2m = 29;
}
switch (mon)
{
case 1:
ret = day;
break;
case 2:
ret = 31 + day;
break;
case 3:
ret = 31 + day_of_2m + day;
break;
case 4:
ret = 31 + day_of_2m + 31 + day;
break;
case 5:
ret = 31 + day_of_2m + 31 + 30 + day;
break;
case 6:
ret = 31 + day_of_2m + 31 + 30 + 31 + day;
break;
case 7:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + day;
break;
case 8:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + day;
break;
case 9:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + day;
break;
case 10:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
break;
case 11:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
break;
case 12:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
break;
}
return ret;
}
當(dāng)時的我是第一次聽說有閏年這個東西(都是書讀的少啊,所以要多讀書爸⑿郎笆!)。
這個時候忘晤,感覺是有一種東西叫時間宛蚓,然后讓我用一種語言把它描述出來。
多年過去了设塔,由于工作原因凄吏,有一個關(guān)于時間的問題,我的狀態(tài)直接回到了當(dāng)時(抓狂)闰蛔。
根據(jù)提供的“年-月-日”來計算第二天的日期
抓狂過后痕钢,我決定“直面慘淡的人生”。
靈光一閃序六,我將其與數(shù)學(xué)的二進制任连、十進制、十六進制聯(lián)系了起來例诀。
年與月為 12 進制
月與日為 28随抠、29裁着、30、31 進制
日與小時為 24 進制
小時與分鐘為 60 進制
分鐘與秒為 60 進制
然后我就寫了這樣的測試代碼:
const int y2y = 10000; /// 年份計算到什么時候結(jié)束, 這里只是為了簡單才設(shè)置該變量
const int y2m = 12; /// 一年擁有的月數(shù)
int m2d = 31; /// 一個月?lián)碛械奶鞌?shù), 變化的
/**
* \brief 將 \saved 與 \num2 以 x 進制的方式相加
相加后的結(jié)果保存到 \saved
返回需要 進位的值 \return
\attention 該處的進制范圍非 0 - (x-1), 而是 1 - x
由于該代碼用于日期拱她,為了方便這樣設(shè)計了進制
*/
int x_add(int *saved, int x, int num2)
{
int ret = 0;
int num1 = *saved;
num1 = num1 + num2;
ret = (num1 - 1) / x;
*saved = (num1 - 1) % x + 1;
return ret;
}
int next_day(int *y, int *m, int *d)
{
int year = *y;
int mon = *m;
int day = *d;
switch (mon)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
m2d = 31;
break;
case 4:
case 6:
case 9:
case 11:
m2d = 30;
break;
case 2:
if (((0 == year % 4) && (0 != year % 100)) ||
(0 == year % 400))
{
m2d = 29;
}
else
{
m2d = 28;
}
break;
}
x_add(&year, y2y,
x_add(&mon, y2m,
x_add(&day, m2d, 1)));
*y = year;
*m = mon;
*d = day;
return 0;
}
我想這時候二驰,我已經(jīng)開始將時間-數(shù)學(xué)-代碼聯(lián)系起來了。
我開始思考了椭懊。這是我得到的結(jié)論诸蚕。
感覺人生就是這樣,從了解規(guī)則到使用規(guī)則氧猬。也許后面是創(chuàng)造規(guī)則背犯。
我們就這樣一步步前進著。
正如 Linus Torvalds 所說:
人類的追求分成三個階段盅抚。
第一是生存漠魏,第二是社會秩序,第三是娛樂妄均。
最明顯的例子是性柱锹,它開始只是一種延續(xù)生命的手段,
后來變成了一種社會行為丰包,
比如你要結(jié)婚才能得到性禁熏。再后來,它成了一種娛樂邑彪。
在《偉大是熬出來的》也有類似的觀點瞧毙,它是這樣描述文明的:
所謂文明,就是把生活變得越來越復(fù)雜
我經(jīng)常會有這樣的迷茫:生活到底為了什么寄症?
有朋友告訴我說:等死宙彪!
也有朋友告訴我說:為了更好的活著!
《士兵突擊》里的許三多說:有意義就是好好活有巧,好好活就是做有意義的事释漆。
而我想,我們活著都在進行這樣一個流程:
第一階段:了解我們所生活的世界的規(guī)則篮迎,然后活下來
第二階段:我們利用我們在第一階段學(xué)習(xí)到的的規(guī)則來使我們生活的更好
第三階段:我們試圖創(chuàng)造新的規(guī)則來使我們生活的更好
這是我現(xiàn)階段所理解的世界男图,也許某一天,我所理解的世界不是這樣了柑潦。
讀書使我明白生活的意義享言。
Keep hungry, keep foolish.
附上所有的代碼(包括另一種處理“根據(jù)提供的“年-月-日”來計算第二天的日期”問題的方法)
/**
* \brief 關(guān)于時間-數(shù)學(xué)-編碼的思考
*/
#include <stdio.h>
#include <stdlib.h>
const int y2y = 10000; /// 年份計算到什么時候結(jié)束, 這里只是為了簡單才設(shè)置該變量
const int y2m = 12; /// 一年擁有的月數(shù)
int m2d = 31; /// 一個月?lián)碛械奶鞌?shù), 變化的
/**
* \brief 將 \saved 與 \num2 以 x 進制的方式相加
相加后的結(jié)果保存到 \saved
返回需要 進位的值 \return
\attention 該處的進制范圍非 0 - (x-1), 而是 1 - x
由于該代碼用于日期,為了方便這樣設(shè)計了進制
*/
int x_add(int *saved, int x, int num2)
{
int ret = 0;
int num1 = *saved;
num1 = num1 + num2;
ret = (num1 - 1) / x;
*saved = (num1 - 1) % x + 1;
return ret;
}
int next_day(int *y, int *m, int *d)
{
int year = *y;
int mon = *m;
int day = *d;
switch (mon)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
m2d = 31;
break;
case 4:
case 6:
case 9:
case 11:
m2d = 30;
break;
case 2:
if (((0 == year % 4) && (0 != year % 100)) ||
(0 == year % 400))
{
m2d = 29;
}
else
{
m2d = 28;
}
break;
}
x_add(&year, y2y,
x_add(&mon, y2m,
x_add(&day, m2d, 1)));
*y = year;
*m = mon;
*d = day;
return 0;
}
int day_of_year(int year, int mon, int day)
{
int ret = 0;
int day_of_2m = 28;
if (((0 == year % 4) && (0 != year % 100)) ||
(0 == year % 400))
{
day_of_2m = 29;
}
switch (mon)
{
case 1:
ret = day;
break;
case 2:
ret = 31 + day;
break;
case 3:
ret = 31 + day_of_2m + day;
break;
case 4:
ret = 31 + day_of_2m + 31 + day;
break;
case 5:
ret = 31 + day_of_2m + 31 + 30 + day;
break;
case 6:
ret = 31 + day_of_2m + 31 + 30 + 31 + day;
break;
case 7:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + day;
break;
case 8:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + day;
break;
case 9:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + day;
break;
case 10:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
break;
case 11:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
break;
case 12:
ret = 31 + day_of_2m + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
break;
}
return ret;
}
int day_of_year_v2(int year, int mon, int day)
{
int ret = 0;
int day_of_2m = 28;
if (((0 == year % 4) && (0 != year % 100)) ||
(0 == year % 400))
{
day_of_2m = 29;
}
switch (mon)
{
case 12:
ret += 30;
case 11:
ret += 31;
case 10:
ret += 30;
case 9:
ret += 31;
case 8:
ret += 31;
case 7:
ret += 30;
case 6:
ret += 31;
case 5:
ret += 30;
case 4:
ret += 31;
case 3:
ret += day_of_2m;
case 2:
ret += 31;
case 1:
ret += day;
break;
}
return ret;
}
int main()
{
int year = 2016;
int mon = 7;
int day = 23;
printf("Today is: %04d-%02d-%02d \n", year, mon, day);
next_day(&year, &mon, &day);
printf("Tomorrow is: %04d-%02d-%02d \n", year, mon, day);
printf("%04d-%02d-%02d is %d th day of this year.\n", year, mon, day, day_of_year(year, mon, day));
printf("%04d-%02d-%02d is %d th day of this year.\n", year, mon, day, day_of_year_v2(year, mon, day));
printf("Hello world!\n");
return 0;
}