4

这是合法的吗?给定格式为 YYYYMMDDHHMMSS 的字符串,我试图尽快到达 time_t。

static time_t ConvertToSecSince1970(char *szYYYYMMDDHHMMSS)
{
struct tm    Tm;    

    memset(&Tm, 0, sizeof(Tm));
    Tm.tm_year = makeInt(szYYYYMMDDHHMMSS +  0, 4) - 1900;
    Tm.tm_mon  = makeInt(szYYYYMMDDHHMMSS +  4, 2) - 1;
    Tm.tm_mday = makeInt(szYYYYMMDDHHMMSS +  6, 2);
    Tm.tm_hour = makeInt(szYYYYMMDDHHMMSS +  8, 2);
    Tm.tm_min  = makeInt(szYYYYMMDDHHMMSS + 10, 2);
    Tm.tm_sec  = makeInt(szYYYYMMDDHHMMSS + 12, 2);
    return mktime(&Tm);
}

如果我使用以下方法创建 TM,它似乎会产生相同的答案:

strptime(szYYYYMMDDHHMMSS, "%Y%m%d%H%M%S", &Tm);

我担心 tm_yday、tm_wday、tm_isdst、tm_gmtoff、tm_zone 很重要。我的日期是 UTC,所以我认为 gmtoff = 0 和 tm_zone = 0 可能有效。

顺便说一下,这里是 makeInt:

inline int makeInt(const char *p, int size)
{
    const char *endp;
    int intval = 0;

    endp = p + size;
    while (p < endp)
    {
        intval = intval * 10 + *p - '0';
        p++;
    }
    return intval;
}
4

3 回答 3

4

除非您确定它太慢,否则使用getdate可能会更好。否则,如果不是有点神秘的话,你正在做的事情看起来还不错。

于 2011-06-10T02:28:10.573 回答
2

mktime()忽略tm_wdayandtm_yday字段,并根据其他字段为它们计算新值。这同样适用于 BSD 扩展tm_gmtofftm_zone,除了它们是从本地时区计算的。

但是请注意,它mktime()使用的是本地时间,而不是 UTC,因此如果您的输入日期是 UTC,那么您的时区必须设置为 UTC。

于 2011-06-10T03:13:26.480 回答
1

一般来说,日期和时间处理有很多棘手的问题,所以我强烈推荐 strptime() 而不是自己动手。如果 strptime() 的性能是瓶颈,请以其他方式解决它,而不是尝试创建更好的 strptime(),例如

  1. 您的字符串以及 time_t (通常使用)仅提供秒精度,因此您可以缓存转换后的值并每秒仅更新一次。

  2. 首先不要使用字符串形式的时间戳。例如,传递一个 time_t 值(包含 time() 返回的纪元以来的秒数),并且仅在/如果您需要将其打印/显示给用户/时将其转换为字符串。

于 2011-06-10T06:48:15.010 回答