SetupBBS 板


LINE

转录到这之後附注说明 : (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: [email protected] %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







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP