minix中时间转换的实现(asctime.c)

在minix2.0源代码中,有相当经典的时间转换函数实现(src\ src\ lib\ ansi\ asctime.c),今天我们就来分析一下asctime.c中的源码

首先引入几个相关的头文件:

1、time.h 主要的结构体与相关定义:

struct tm {
  int tm_sec;            /* 分钟后面的秒[0, 59] */
  int tm_min;            /* 小时后面的分钟[0, 59] */
  int tm_hour;            /* 距离凌晨00:00点的小时数[0, 23] */
  int tm_mday;            /* 月中的某一天[1, 31] */
  int tm_mon;            /* 某一个月份[0, 11] */
  int tm_year;            /* 与1900相隔的年数 */
  int tm_wday;            /* 离星期日的天数 [0, 6] */
  int tm_yday;            /* 从一月开始的天数 [0, 365] */
  int tm_isdst;            /* Daylight Saving Time flag */
};
char *asctime(const struct tm *_timeptr)

2、loc_time.h

#define    YEAR0        1900        /*第一年*/
#define    EPOCH_YR    1970        /* EPOCH = Jan 1 1970 00:00:00 */
#define    SECS_DAY    (24L * 60L * 60L)
#define    LEAPYEAR(year)    (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define    YEARSIZE(year)    (LEAPYEAR(year) ? 366 : 365)
#define    FIRSTSUNDAY(timp)    (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
#define    FIRSTDAYOF(timp)    (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
#define    TIME_MAX    ULONG_MAX
#define    ABB_LEN        3

extern const int _ytab[2][12];
extern const char *_days[];
extern const char *_months[];

void _tzset(void);
unsigned _dstget(struct tm *timep);

extern long _timezone;
extern long _dst_off;
extern int _daylight;
extern char *_tzname[2];

3、asctime.c

#include    <string.h>
#include    <time.h>
#include    "loc_time.h"

#define    DATE_STR    "??? ??? ?? ??:??:?? ????\n"      //时间格式

static char * two_digits(register char *pb, int i, int nospace)  
{
    //将两位数字转化为字符形式并存储在pb所指向的地址空间中
    *pb = (i / 10) % 10 + '0';
    if (!nospace && *pb == '0') *pb = ' ';
    pb++;
    *pb++ = (i % 10) + '0';
    return ++pb;
}

static char * four_digits(register char *pb, int i)                
{
    //将四位数字转化为字符形式并存储在pb所指向的地址空间中  
    i %= 10000;
    *pb++ = (i / 1000) + '0';
    i %= 1000;
    *pb++ = (i / 100) + '0';
    i %= 100;
    *pb++ = (i / 10) + '0';
    *pb++ = (i % 10) + '0';
    return ++pb;
}

char *asctime(const struct tm *timeptr)   //把timeptr指向的tm结构体中储存的时间转换为字符串格式返回。
{                                         // 格式为:Www Mmm dd hh:mm:ss yyyy。
                                          //其中Www为星期;Mmm为月份;dd为日;hh为时;mm为分;ss为秒;yyyy为年份。
    static char buf[26];
    register char *pb = buf;
    register const char *ps;
    register int n;

    strcpy(pb, DATE_STR);          //对buf进行标准格式初始化:  pb-> ??? ??? ?? ??:??:?? ????\n
    ps = _days[timeptr->tm_wday];    //extern const char *_days[];
    n = ABB_LEN;                   //#define   ABB_LEN  3
    while(--n >= 0) *pb++ = *ps++;
    pb++;
    ps = _months[timeptr->tm_mon];
    n = ABB_LEN;
    while(--n >= 0) *pb++ = *ps++;
    pb++;
    pb = two_digits(
            two_digits(
                two_digits(two_digits(pb, timeptr->tm_mday, 0)
                    , timeptr->tm_hour, 1)
                , timeptr->tm_min, 1)
            , timeptr->tm_sec, 1);

    four_digits(pb, timeptr->tm_year + 1900);
    return buf;
}
原文地址:https://www.cnblogs.com/cpoint/p/3367484.html