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