"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) != '\0') {
        /* 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\n",ts);
    return(0);
}
*/
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python的strptime函数是datetime库中的一个函数,用于将一个日期字符串转换为datetime日期格式,以便后续处理。它的使用格式为`datetime.strptime(date_string, format)`,其中`date_string`是要转换为日期的字符串,`format`是根据`date_string`的不同而不同的格式。通过指定正确的格式,可以将字符串解析为对应的日期时间值。 例如,我们可以使用以下代码来演示strptime函数的使用: ```python import datetime as dt date_str1 = '2020-10-1' date_str2 = '2020/09/24' real_time1 = dt.datetime.strptime(date_str1, '%Y-%m-%d') real_time2 = dt.datetime.strptime(date_str2, '%Y/%m/%d') print(real_time1) # 输出:2020-10-01 00:00:00 print(real_time2) # 输出:2020-09-24 00:00:00 time_delta = real_time1 - real_time2 print(time_delta) # 输出:7 days, 0:00:00 print(time_delta.days) # 输出:7 ``` 在这个例子中,我们使用strptime函数将两个日期字符串转换为datetime日期格式的对象,然后计算它们之间的时间差,并打印出结果。`%Y-%m-%d`和`%Y/%m/%d`分别是日期字符串的格式,用于指定每个部分的顺序和分隔符。 总之,Python的strptime函数是一个强大的工具,可以将日期字符串转换为datetime日期格式,以便进行日期和时间的处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Python 中 strptime()方法的使用](https://blog.csdn.net/mayang2015/article/details/108770484)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [python中datetime模块中strftime/strptime函数的使用](https://download.csdn.net/download/weixin_38739101/12867854)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Python (13) strptime()函数](https://blog.csdn.net/weixin_42221654/article/details/128102621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值