轉錄到這之後附註說明 :
(1) 因為文章不見 有人寫信予我這裡看比較方便 ... (其實我覺得到出處看就好 ...)
(2) 以往 我們都是用 time_t now = time(NULL); 取得 timestamp 後用 ctime() 去
秀出 YYYY MM DD hh rr ss (格式看用那個函式 也有自訂函式) 可是我們無法用
YYYY MM DD (本程式以 day 為基準省略 hh mm <即只以第一天的第 0 小時 0 分
為算出值 本程式 當然 可擴充 再輸入 時(hh) 分(mm) 秒(ss)> 於此略之)
#include <stdio.h>
#include <time.h>
int main(void) {
time_t now = time(NULL);
printf("%d\n%s\n", (int)now, ctime(&now));
return 0;
}
我們如果得到一個 stamp 值 1263225600 代入 ctime() 即可顯示我們所知的時制 :
#include <stdio.h>
#include <time.h>
int main(void) {
time_t now = 1263225600;
printf("%s\n", ctime(&now));
return 0;
}
會得到這樣的結果 :
Tue Jan 12 00:00:00 2010
我們要算 2010/01/15 00:00:00 的 timestamp 怎算 ? 很簡單 把 2010/01/12 的
timestamp 加上 86400x3 即可 加減都可以比照
但是 ...
那 我們有沒有辦法輸入 2010 01 12 然後得到 stamp 值呢 ? 很遺憾的 在 ANSI-C
中 並沒有 這樣的東西
有人或許會問了 要這種東西做啥 ?
最簡單的問題應用 -> 求 A B 兩時間點差了多久
"民國 96 年 11 月 16 日" 跟 "民國 85 年 11 月 16 日" 差了幾天 ?
這問題很單純 他們差了11 年 那 11 年是差幾天 ? 365x11 ? 不是吧 ... 原因很
簡單 閏年問題 所以我們計算時要加上 '中間經過幾個閏年'
好 這可能還是個簡單的問題 那麼來點比較長的時間
"民國 97 年 03 月 02 日" 跟 "民國 68 年 05 月 16 日" 差了幾天 ?
算出 多一年的 3/02 跟 5/16 差幾天 再乘以不足年數 x365 天 再加閏年有幾個
很好 如果每個日期都這樣比對 即時運算會很 ... 我想大家知道我的意思 ...
又有人會說 阿就 difftime() 套下去就好啦 ? 可是 ... 有這麼簡單嗎 ?
來看原式宣告 double difftime(time_t time1, time_t time0);
time_t 可是 integer 喔 可不是啥 [CC]YY/MM/DD 這麼單純 如我有這種東西我
也想用 (其實 有個秘密 ... 懂 本程式 你可以自己寫一個
int diff_date(char *date1, char *date2); // date 1/2 as yyyy/mm/dd
到時就可這樣叫用 diff_date("2009/12/18", "1997/12/19");
(這兩個日期的梗相信鄉民知道 :p)
簡而言之 沒有真的實作過人的不會知道 "沒有可用函式" 的心酸 :p
所以 我這篇文章其實是把行之有年的東東 公開 來 !!!
如果 還不知道這個函式有 ~多麼好用~ 看倌們就當作是看看小學數學習題亦可 :)
X X X
作者 Dopin (系統調校完成) 看板 InstallBBS
標題 <轉錄> 受不了 ...
時間 Wed Dec 16 23:16:06 2009
───────────────────────────────────────
※ [本文轉錄自 ATSVersion 看板]
作者: Dopin (系統調校完成) 看板: ATSVersion
標題: 受不了 ...
時間: Wed Dec 16 06:17:21 2009
想說要把自動連署寫的更完備些 舊程式遇到跨年就死了 - -;;; 所以我想找個能把
yyyy/dd/mm 轉成 timestamp 的程式 這樣純數值減法問題會少很多 不用啥比月份
大小完再比日期 遇到年份不同再比 ... 囉唆的要命 Orz
我依稀這玩意兒國中還高中讀書時代寫過 (那時是賺外快幫個漫畫店寫 Clipper 遇
到沒有 yyyymmdd 的好用解 而 DBASE 內建的東西又爛的要死 所以 "開發的" (扛
成 .obj 拿來 link 用 Orz)
不幸的是以前的實作法真的給他忘記了 ... 我只記得有用到 difftime() 之類函式
(也許有記錯 我記得是 Turbo C 下寫的) 但實在想不起來程式片段的詳細到底是怎
樣 而且那時就愛耍帥 喜歡把程式寫的讓人看不懂 最後 ... 看不懂的往往是自己
(還喜歡在 C 裡 inline ASM - -;;;)
人懶 沒藥醫 上網找有沒有現成的函式可以用 (不要臉 :p)
但是 !!! 找半天沒找著 (怒) 只找到個網站有類似討論的 :
http://www.lslnet.com/linux/f/docs1/i41/big5291280.htm
(再次強調 我是要找 ANSI-C 的解法) 但是進去看發現不是寫的亂七八糟 就是根本
寫錯 而且 還有人居然對其他討論者這樣寫道 :
"特大喜訊,我給你發了. 公司機密文件,僅限站內朋友,請勿外傳,謝謝."
或是什麼 "不過不要敲我的飯碗啊." "收到,謝謝,不敢外傳!" 都可以說 ...
我的天 這又不是啥偉大或獨門的演算法 :p
不過熱心助人是不能否定的 能用當然是歡樂 ^OO^ 無奈 ... 略 "喵" 了該網頁的範
例 兩個都寫的亂七八糟(第三個只是把時間函式列出來 <核爆>) 看到那種縮排 我自
己搞都比較快 所以啦 就這樣辦 = =b (GOGOGOGO !!!)
說嘴 : 下面那篇文章的程式 "完全不是" 啥了不起的東西 不過要是拿去用可要說
這是 Dopin 的解法 (再次不要臉 XD ... 冷掉了)
--
Origin: Atlantis DN: bbs.bsd.com.tw IP : 203.70.65.27 ST: atlantis
X X X
作者 Dopin (系統調校完成) 看板 InstallBBS
標題 <轉錄> src/maple/date_stamp.c (拿到 maple/ 下扛最快 :p)
時間 Wed Dec 16 23:16:16 2009
───────────────────────────────────────
※ [本文轉錄自 ATSVersion 看板]
作者: Dopin (系統調校完成) 看板: ATSVersion
標題: src/maple/date_stamp.c (拿到 maple/ 下扛最快 :p)
時間: Wed Dec 16 06:26:15 2009
/*-------------------------------------------------------*/
/* date_stamp.c ( Atlantis BBS Ver 1.32 ) */
/*-------------------------------------------------------*/
/* target : 將 yyyy mm dd 的引數轉換成 time stamp */
/* create : 2009/12/16 (Dopin) */
/* update : / / */
/*-------------------------------------------------------*/
/* syntex : date_stamp <yyyy> <mm> <dd> */
/*-------------------------------------------------------*/
#include "bbs.h"
// ats 1.32 append 小學例題 計算閏年 我還故意用很 "易懂" 的回傳法 :p
int check_bissextile(int y) {
/* 逢 四年 閏 逢 百年 不閏 逢 百年 且 逢 四百年 又閏 */
return !(y % 4) && ((y % 100) || !(y % 100) && !(y % 400)) ;
}
// ats 1.32 append 小學例題 判定年月日是否合理 本程式不考慮 1970 年前
// 也缺乏詳細的每月檢查(只查閏月)有需要嚴格檢查自己改
int chack_yyyymmdd(int y, int m, int d) {
if(y < 1970) return -1;
if(m > 12 || m < 1) return -2;
if(d > 31 || d < 1) return -3;
if(m == 2 &&
(check_bissextile(y) && d > 29 || !check_bissextile(y) && d > 28))
return -4;
return 0;
}
// ats 1.32 append 計算 yyyymmdd 的 timestamp 究極土法鍊鋼 才是王道 (挺)
int yyyymmdd_to_stamp(int y, int m, int d) {
char day[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 0 };
int i, days = 0; /* 沒人需要 12 月 除非整年要從一加到十二月 ! */
// 加到前一年
for(i = 1970 ; i < y ; i++) days += check_bissextile(i) ? 366 : 365;
// 加到前一月
for(i = 1 ; i < m ; i++) days += day[i - 1];
// 加到當天
days += d;
// 該年為閏年且超過 二月 (因為閏月格式先前已檢查過) 加一天
if(check_bissextile(y) && m > 2) days += 1;
// 多減一天的原因是 1970 年的 1 月 1 號 是 0 所以含了當天會 "多算一天"
// 多減 8 小時的原因是因為我們用 GMT 跟 CST 差八小時 隨時區不同要調整
return days * 86400 - 86400 - 8 * 3600 ;
}
/* 以上的函式 我會加到之後的 dopin.c / dopin.h 之中 這程式沒有 Y2K 問題 */
int main(int argc, char *argv[]) {
int y, m, d, error;
time_t stamp;
if(argc != 4) {
puts("syntex: date_stamp <yyyy> <mm> <dd>");
return -1;
}
y = atoi(argv[1]);
m = atoi(argv[2]);
d = atoi(argv[3]);
if(error = chack_yyyymmdd(y, m, d)) {
printf("date error ! Code : %d\n", error);
return -2;
}
stamp = (time_t)yyyymmdd_to_stamp(y, m, d);
printf("[ %d ]\n", (int)stamp);
/* 這行純驗證用 覺得不需要就可以拿掉他 */
printf("%s", ctime(&stamp));
return 0;
}
--
Origin: Atlantis DN: bbs.bsd.com.tw IP : 203.70.65.27 ST: atlantis
X X X
作者 Dopin (系統調校完成) 看板 InstallBBS
標題 <轉錄> Re: src/maple/date_stamp.c (拿到 maple/ 下扛最快 …
時間 Wed Dec 16 23:16:27 2009
───────────────────────────────────────
※ [本文轉錄自 ATSVersion 看板]
作者: Dopin (系統調校完成) 看板: ATSVersion
標題: Re: src/maple/date_stamp.c (拿到 maple/ 下扛最快 …
時間: Wed Dec 16 06:32:33 2009
In-Reply-To: 4jPOQe$lG_@bbs.bsd.com.tw
%make date_stamp
gcc -O2 -I../include date_stamp.c -o date_stamp
%./date_stamp 1983 02 27
[ 415123200 ]
Sun Feb 27 00:00:00 1983
%./date_stamp 2009 12 16
[ 1260892800 ]
Wed Dec 16 00:00:00 2009
%./date_stamp 2004 2 29
[ 1077984000 ]
Sun Feb 29 00:00:00 2004
%./date_stamp 1970 1 1
[ -28800 ]
Thu Jan 1 00:00:00 1970
%
所以用法簡單易懂 科科 特別注意您所使用的伺服器時間 如果有錯誤
記得要調整時區 或是把那個 - 8 * 3600 給拿掉 才能正確算出數值
最後 因為 signed int (32bits) 的極值問題 這個程式的最高極限日
期數值 是 2147443200 也就是 2038/01/19 超過就會出鎚 :p 真的想
要做點限制避免算錯 在比對日期格式的函式部份再動點手腳就好
最後實際用到應用上 比方要計算 2006/01/13 與 1986/12/07 差了幾
天 只要各自求出 stamp 數值 彼此相減後再除以秒數即可 如果真的只
需要算差幾天就夠了 86400 部份修改掉就好
[本程式範例皆以 32bits 環境為基準]
--
Origin: Atlantis DN: bbs.bsd.com.tw IP : 203.70.65.27 ST: atlantis
--
SOB Pack 已於日前 Release 出 gcc 4.x 版, 歡迎還活在 Maple 2.36 SOB Version
回憶中的朋友們一起來討論下列相關 :
1. maple 2.36 2. SOB 3. Atlantis Version
telnet to bbs.bsd.com.tw Boardname : ATSVersion
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 203.70.65.27