• "undefined reference to strptime"之自己定义strptime函数


    简单介绍

      strptime()函数可以依照特定时间格式将字符串转换为时间类型。简单点说可以将字符串时间转化为时间戳。

    这个函数包括在time.h头文件里,在Unix或者类Unix系统中,我们会常常接触到。可是到了跑Nuttx系统的Pixhawk。真是醉了,非常多东西都没有,或者少了非常多东西,比方time.h中就没有这个函数的实现,又如dirent.h中的一些文件类型的宏定义也没有了。

    可是我们非常须要,比方在时间的比較上,我们不能去拿字符串去操作来比較。会搞死人的。直接得到时间戳,三下两除二就搞定了。那就要用到strptime这个函数了。

    实现

    mystrptime.c
    
    /*
     * Note:因time.h中没有strptime函数(UNIX中是有的),本文件是对strptime功能的自己定义实现;
     * We do not implement alternate representations. However, we always
     * check whether a given modifier is allowed for a certain conversion.
     */
    #include "mystrptime.h"
    
    
    static const char *day[7] = {
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday"
    };
    static const char *abday[7] = {
        "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
    };
    static const char *mon[12] = {
        "January", "February", "March", "April", "May", "June", "July",
        "August", "September", "October", "November", "December"
    };
    static const char *abmon[12] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
    static const char *am_pm[2] = {
        "AM", "PM"
    };
    
    
    static int conv_num(const char **buf, int *dest, int llim, int ulim)
    {
        int result = 0;
    
        /* The limit also determines the number of valid digits. */
        int rulim = ulim;
    
        if (**buf < '0' || **buf > '9')
            return (0);
    
        do {
            result *= 10;
            result += *(*buf)++ - '0';
            rulim /= 10;
        } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
    
        if (result < llim || result > ulim)
            return (0);
    
        *dest = result;
        return (1);
    }
    
    char * mystrptime(const char *buf, const char *fmt, struct tm *tm)
    {
        char c;
        const char *bp;
        size_t len = 0;
        int alt_format, i, split_year = 0;
    
        bp = buf;
    
        while ((c = *fmt) != '') {
            /* Clear `alternate' modifier prior to new conversion. */
            alt_format = 0;
    
            /* Eat up white-space. */
            if (isspace(c)) {
                while (isspace(*bp))
                    bp++;
    
                fmt++;
                continue;
            }
    
            if ((c = *fmt++) != '%')
                goto literal;
    
    
    again:      switch (c = *fmt++) {
            case '%':   /* "%%" is converted to "%". */
    literal:
                if (c != *bp++)
                    return (0);
                break;
    
            /*
             * "Alternative" modifiers. Just set the appropriate flag
             * and start over again.
             */
            case 'E':   /* "%E?" alternative conversion modifier. */
                LEGAL_ALT(0);
                alt_format |= ALT_E;
                goto again;
    
            case 'O':   /* "%O?" alternative conversion modifier. */
                LEGAL_ALT(0);
                alt_format |= ALT_O;
                goto again;
    
            /*
             * "Complex" conversion rules, implemented through recursion.
             */
            case 'c':   /* Date and time, using the locale's format. */
                LEGAL_ALT(ALT_E);
                if (!(bp = mystrptime(bp, "%x %X", tm)))
                    return (0);
                break;
    
            case 'D':   /* The date as "%m/%d/%y". */
                LEGAL_ALT(0);
                if (!(bp = mystrptime(bp, "%m/%d/%y", tm)))
                    return (0);
                break;
    
            case 'R':   /* The time as "%H:%M". */
                LEGAL_ALT(0);
                if (!(bp = mystrptime(bp, "%H:%M", tm)))
                    return (0);
                break;
    
            case 'r':   /* The time in 12-hour clock representation. */
                LEGAL_ALT(0);
                if (!(bp = mystrptime(bp, "%I:%M:%S %p", tm)))
                    return (0);
                break;
    
            case 'T':   /* The time as "%H:%M:%S". */
                LEGAL_ALT(0);
                if (!(bp = mystrptime(bp, "%H:%M:%S", tm)))
                    return (0);
                break;
    
            case 'X':   /* The time, using the locale's format. */
                LEGAL_ALT(ALT_E);
                if (!(bp = mystrptime(bp, "%H:%M:%S", tm)))
                    return (0);
                break;
    
            case 'x':   /* The date, using the locale's format. */
                LEGAL_ALT(ALT_E);
                if (!(bp = mystrptime(bp, "%m/%d/%y", tm)))
                    return (0);
                break;
    
            /*
             * "Elementary" conversion rules.
             */
            case 'A':   /* The day of week, using the locale's form. */
            case 'a':
                LEGAL_ALT(0);
                for (i = 0; i < 7; i++) {
                    /* Full name. */
                    len = strlen(day[i]);
                    if (strncasecmp(day[i], bp, len) == 0)
                        break;
    
                    /* Abbreviated name. */
                    len = strlen(abday[i]);
                    if (strncasecmp(abday[i], bp, len) == 0)
                        break;
                }
    
                /* Nothing matched. */
                if (i == 7)
                    return (0);
    
                tm->tm_wday = i;
                bp += len;
                break;
    
            case 'B':   /* The month, using the locale's form. */
            case 'b':
            case 'h':
                LEGAL_ALT(0);
                for (i = 0; i < 12; i++) {
                    /* Full name. */
                    len = strlen(mon[i]);
                    if (strncasecmp(mon[i], bp, len) == 0)
                        break;
    
                    /* Abbreviated name. */
                    len = strlen(abmon[i]);
                    if (strncasecmp(abmon[i], bp, len) == 0)
                        break;
                }
    
                /* Nothing matched. */
                if (i == 12)
                    return (0);
    
                tm->tm_mon = i;
                bp += len;
                break;
    
            case 'C':   /* The century number. */
                LEGAL_ALT(ALT_E);
                if (!(conv_num(&bp, &i, 0, 99)))
                    return (0);
    
                if (split_year) {
                    tm->tm_year = (tm->tm_year % 100) + (i * 100);
                } else {
                    tm->tm_year = i * 100;
                    split_year = 1;
                }
                break;
    
            case 'd':   /* The day of month. */
            case 'e':
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_mday, 1, 31)))
                    return (0);
                break;
    
            case 'k':   /* The hour (24-hour clock representation). */
                LEGAL_ALT(0);
                /* FALLTHROUGH */
            case 'H':
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_hour, 0, 23)))
                    return (0);
                break;
    
            case 'l':   /* The hour (12-hour clock representation). */
                LEGAL_ALT(0);
                /* FALLTHROUGH */
            case 'I':
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_hour, 1, 12)))
                    return (0);
                if (tm->tm_hour == 12)
                    tm->tm_hour = 0;
                break;
    
            case 'j':   /* The day of year. */
                LEGAL_ALT(0);
                if (!(conv_num(&bp, &i, 1, 366)))
                    return (0);
                tm->tm_yday = i - 1;
                break;
    
            case 'M':   /* The minute. */
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_min, 0, 59)))
                    return (0);
                break;
    
            case 'm':   /* The month. */
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &i, 1, 12)))
                    return (0);
                tm->tm_mon = i - 1;
                break;
    
            case 'p':   /* The locale's equivalent of AM/PM. */
                LEGAL_ALT(0);
                /* AM? */
                if (strcasecmp(am_pm[0], bp) == 0) {
                    if (tm->tm_hour > 11)
                        return (0);
    
                    bp += strlen(am_pm[0]);
                    break;
                }
                /* PM? */
                else if (strcasecmp(am_pm[1], bp) == 0) {
                    if (tm->tm_hour > 11)
                        return (0);
    
                    tm->tm_hour += 12;
                    bp += strlen(am_pm[1]);
                    break;
                }
    
                /* Nothing matched. */
                return (0);
    
            case 'S':   /* The seconds. */
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_sec, 0, 61)))
                    return (0);
                break;
    
            case 'U':   /* The week of year, beginning on sunday. */
            case 'W':   /* The week of year, beginning on monday. */
                LEGAL_ALT(ALT_O);
                /*
                 * XXX This is bogus, as we can not assume any valid
                 * information present in the tm structure at this
                 * point to calculate a real value, so just check the
                 * range for now.
                 */
                 if (!(conv_num(&bp, &i, 0, 53)))
                    return (0);
                 break;
    
            case 'w':   /* The day of week, beginning on sunday. */
                LEGAL_ALT(ALT_O);
                if (!(conv_num(&bp, &tm->tm_wday, 0, 6)))
                    return (0);
                break;
    
            case 'Y':   /* The year. */
                LEGAL_ALT(ALT_E);
                if (!(conv_num(&bp, &i, 0, 9999)))
                    return (0);
    
                tm->tm_year = i - TM_YEAR_BASE;
                break;
    
            case 'y':   /* The year within 100 years of the epoch. */
                LEGAL_ALT(ALT_E | ALT_O);
                if (!(conv_num(&bp, &i, 0, 99)))
                    return (0);
    
                if (split_year) {
                    tm->tm_year = ((tm->tm_year / 100) * 100) + i;
                    break;
                }
                split_year = 1;
                if (i <= 68)
                    tm->tm_year = i + 2000 - TM_YEAR_BASE;
                else
                    tm->tm_year = i + 1900 - TM_YEAR_BASE;
                break;
    
            /*
             * Miscellaneous conversions.
             */
            case 'n':   /* Any kind of white-space. */
            case 't':
                LEGAL_ALT(0);
                while (isspace(*bp))
                    bp++;
                break;
    
    
            default:    /* Unknown/unsupported conversion. */
                return (0);
            }
    
    
        }
    
        /* LINTED functional specification */
        return ((char *)bp);
    }
    
    
    time_t to_seconds(const char *date,int mode)
    {
        struct tm storage={0,0,0,0,0,0,0,0,0};
        char *p=NULL;
        time_t retval=0;
    
        if(1 == mode)p=(char *)mystrptime(date,"%Y-%m-%d",&storage);
        else if(0 == mode)p=(char *)mystrptime(date,"%Y_%m_%d",&storage);
        if(p==NULL)
        {
            retval=0;
        }
        else
        {
            retval=mktime(&storage);
        }
        return retval;
    }
    
    mystrptime.h
    
    #ifndef MYSTRPTIME_H_
    #define MYSTRPTIME_H_
    
    #include <stdio.h>
    #include <time.h>
    #include <ctype.h>
    #include <string.h>
    
    #define ALT_E           0x01
    #define ALT_O           0x02
    #define LEGAL_ALT(x)        { if (alt_format & ~(x)) return (0); }
    #define TM_YEAR_BASE 1900
    
    char *mystrptime(const char *buf, const char *fmt, struct tm *tm);
    time_t to_seconds(const char *date,int mode);
    
    #endif

    測试

    /*Test*/
    /*
    #intclude <stdio.h>
    #include "mystrptime.h"
    
    int main ()
    {
        time_t ts;
        ts = to_seconds("2015-07-29",1);
        //ts = to_seconds("2015_07_29",0);
        printf("ts=%d
    ",ts);
        return(0);
    }
    */
    
  • 相关阅读:
    LeetCode #53 Maximum Subarray 最大子数组 分治 线性DP
    POJ #2726 Holiday Hotel 快排
    《算法导论》第四章 练习题 Exercise
    POJ #1579 Function Run Fun 记忆化搜索
    《算法导论》第三章 练习题 Exercise
    《算法导论》 第二章 练习题 Exercise
    C语言数据类型
    codeblocks常用快捷键
    java 构造函数
    参考文献标注
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8594174.html
Copyright © 2020-2023  润新知