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_wdayおよびフィールドを無視しtm_yday、他のフィールドに基づいてそれらの新しい値を計算します。ローカル タイム ゾーンから計算されることを除いて、同じことが BSD 拡張機能tm_gmtoffおよびにも当てはまります。tm_zone

ただし、 UTC ではなく現地mktime()時間を使用することに注意してください。入力日付が UTC の場合は、タイムゾーンを UTC に設定する必要があります。

于 2011-06-10T03:13:26.480 に答える
1

一般に、日付と時刻の処理には多くのトリッキーな落とし穴があるため、自分で作成するよりも strptime() を強くお勧めします。strptime() のパフォーマンスがボトルネックである場合は、より優れた strptime() を作成する以外の方法で回避してください。

  1. 文字列と time_t (通常使用される) は秒の精度しか提供しないため、変換された値をキャッシュして、1 秒に 1 回だけ更新することができます。

  2. そもそも、文字列形式のタイムスタンプを使用しないでください。たとえば、代わりに time_t 値 (time() によって返されるエポックからの秒数を含む) を渡し、印刷する必要がある場合/ユーザーに表示する必要がある場合にのみ文字列に変換します。

于 2011-06-10T06:48:15.010 に答える