九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

一天一个C Run-Time Library 函数 (7) asctime(时间函数)


一天一个C Run-Time Library 函数 (7)  asctime(时间函数)

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

msdn:

Convert a tm time structure to a character
string. These functions are deprecated because more secure versions are
available; see asctime_s,

char
*asctime(

   const struct tm *timeptr

);

测试程序:

#include <stdio.h>

#include <time.h>

 

 

 

int main( void )

{

 

    time_t ltNow = time(NULL);

    struct tm*
lptmNow = localtime(&ltNow);

 

    const char*
lpszNow = asctime(lptmNow);

 

   

    printf("%s",lpszNow);

 

 

    return 0;

}

 

 

说明:

asctime是非常使用的函数,与time(),localtimegmtimemktime,ctime一起构成了C语言世界的时间概念。C中的格林威治时间体系就是由这几个函数来完成的。time_t类型是用来沟通这些函数的桥梁。说明一下,localtime在转换的时候是根据本地locale来转换的,gmtime就是转换标准的格林威治时间,(似乎从结果上来看就是转换成了伦敦时间)。顺便说一下,以_t结尾的类型定义虽然你在Windows中看到是可能是简单的int型,但是即使这样,作为可移植的程序开发,还是应该用原来的类型定义,这样碰到不同实现的时候不至于会导致错误,比如windows中现在time_t现在默认的就是int64了。

与此类似的类型还有pid_t,win_t

实现:

static _TSCHAR * __cdecl store_dt (

    REG1 _TSCHAR *p,

    REG2 int val

    )

{

    *p++ = (_TSCHAR)(_T('0') + val /
10);

    *p++ = (_TSCHAR)(_T('0') + val %
10);

    return(p);

}

 

    REG2 _TSCHAR *p = buffer;

    int day, mon;

    int i;

    day = tb->tm_wday
* 3;      /*
index to correct day string */

    mon = tb->tm_mon *
3;       /*
index to correct month string */

    for (i=0; i < 3; i++,p++) {

        *p =
*(__dnames + day
+ i);

        *(p+4)
= *(__mnames + mon
+ i);

    }

 

    *p = _T(' ');           /* blank
between day and month */

 

    p += 4;

 

    *p++ = _T(' ');

    p = store_dt(p, tb->tm_mday);   /* day of the
month (1-31) */

    *p++ = _T(' ');

    p = store_dt(p, tb->tm_hour);   /* hours (0-23) */

    *p++ = _T(':');

    p = store_dt(p, tb->tm_min);    /* minutes (0-59)
*/

    *p++ = _T(':');

    p = store_dt(p, tb->tm_sec);    /* seconds (0-59)
*/

    *p++ = _T(' ');

    p = store_dt(p, 19
+ (tb->tm_year/100));
/* year (after 1900) */

    p = store_dt(p, tb->tm_year%100);

    *p++ = _T('/n');

    *p = _T('/0');

 

 

 

MS:

这个实现是我此系列开始写以后看的源代码中最有意思的源代码了。所以不惜编程源代码的分析都要讲一讲。

很有意思的代码,淋漓尽致的体现了C语言指针的灵活。

for (i=0; i < 3; i++,p++) {

        *p =
*(__dnames + day
+ i);

        *(p+4)
= *(__mnames + mon
+ i);

    }

通过对月和星期的buf,用这个循环完成的6个字符的拷贝更是很让我欣赏:)

通过val/10的加上’0’asc值的方式完成的默认前置0的赋值也是很有意思的技巧。

    *p++ = (_TSCHAR)(_T('0') + val /
10);

*p++ = (_TSCHAR)(_T('0') + val %
10);

 

 

gcc:

仅仅通过一个简单的snprintf来实现,这估计也是大部分人的实现方式。。。。我要是真的准备实现这样一个代码也会这样实现。

 

 

效率测试:

很想知道到底哪个会赢。。。。不过太晚了。。。。

 

 

相关函数:

gmtime,  localtime,  ctime, time,

个人想法:

除了宽字节版本不能使用之外,其他函数的使用自然没有任何问题。并且函数名完全一致。对于这么古老和标准的函数假如还能出现问题,估计任何做可移植程序的人都会崩溃的。放心用吧。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

分类:  C++ 
标签:  asctime  C++ 

Posted By 九天雁翎 at 九天雁翎的博客 on 2008年11月05日

前一篇: 一天一个C Run-Time Library 函数(6) 三角函数 后一篇: 今天开始研究h.264..........