1
        char buffer[800];
        struct tm str_time;

        str_time.tm_mday = Cur_Day;
        str_time.tm_mon = Cur_Month - 1;
        str_time.tm_year = entries[i].Year_Start - 1900;
        int len = strftime(buffer, 100, "%A, %d %B %Y", &str_time);
        printf("\n%s\n", buffer);

上記の結果、Cur_Day と Cur_Month の値に関係なく、曜日は常に日曜日になるのでしょうか?

出力例:

Sunday, 23 November 2012
------------------------
stuff

Sunday, 25 November 2012
------------------------
stuff

Sunday, 26 November 2012
------------------------
stuff
4

3 に答える 3

3

明示的にstr_time設定しない限り、構造体(ローカル変数のように見える場合)のフィールドには不定値があります。持っている値を使用するだけで、他のフィールドに適合するように値を最初に調整することはありません。strftime

を設定していないのでtm_wday、元の状態のままになります (常に日曜日なので、見た目では 0 です)。

他のフィールドに基づいてフィールドを調整たい場合は、 を調べる必要がありますmktime()

標準 (ISO C99) から:

mktime 関数は、timeptr が指す構造体にある、ローカル時間として表される分解された時間を、time 関数によって返される値と同じエンコーディングを使用してカレンダー時間値に変換します。

構造体の tm_wday および tm_yday コンポーネントの元の値は無視され、他のコンポーネントの元の値は上記の範囲に制限されません。

正常に完了すると、構造体の tm_wday および tm_yday コンポーネントの値が適切に設定され、他のコンポーネントは指定された暦時間を表すように設定されますが、それらの値は上記の範囲に強制されます。tm_mon と tm_year が決定されるまで、tm_mday の最終値は設定されません。

あなたの最善の策は、を使用time()localtime()て構造体にデータを入力し、tm変更するフィールドを変更してから を呼び出すことmktime()です。そうすれば、すべてのフィールドが適切な値を持つことが保証されます。

次のプログラムは、これを行う 1 つの方法を示しています。

#include <stdio.h>
#include <time.h>

int main (void) {
    char buffer[100];
    time_t now;
    struct tm *ts;

    // Get today in local time and output it.

    now = time (NULL);
    struct tm *ts = localtime (&now);
    strftime (buffer, 100, "%A, %d %B %Y", ts);
    printf ("Now      = %s\n", buffer);

    // Advance day-of-month and make new date.
    // Probably need to intelligently handle month rollover.

    ts->tm_mday++;
    mktime (ts);
    strftime (buffer, 100, "%A, %d %B %Y", ts);
    printf ("Tomorrow = %s\n", buffer);

    return 0;
}

そのプログラムの出力は次のとおりです。

Now      = Tuesday, 09 October 2012
Tomorrow = Wednesday, 10 October 2012

価値のあるものとして、このメソッドを使用して特定の日付 (デフォルトは今日) の曜日を取得する完全なプログラムを次に示します。

-yオプションの ,-mおよび引数を使用して、年、月、日を-d任意の順序で何度でも変更できますが、各タイプの最後のものだけがカウントされます。

#include <stdio.h>
#include <time.h>

static int makeError (char *argVal, char *errStr) {
    printf ("Error with argument '%s': %s\n", argVal, errStr);
    printf ("Usage: dow [-y<year>] [-m<month>] [-d<day>]\n");
    return 1;
}

int main (int argc, char *argv[]) {
    int idx, intVal;
    char chVal;
    char buff[100];
    time_t now = time (NULL);
    struct tm *nowStr = localtime (&now);

    for (idx = 1; idx < argc; idx++) {
        chVal = (*argv[idx] != '-') ? '\0' : *(argv[idx] + 1);
        if ((chVal != 'y') && (chVal != 'm') && (chVal != 'd'))
            return makeError (argv[idx], "does not start with '-y/m/d'");

        intVal = atoi (argv[idx] + 2);
        if (intVal < 0)
            return makeError (argv[idx], "suffix is negative");
        sprintf (buff, "%d", intVal);
        if (strcmp (buff, argv[idx] + 2) != 0)
            return makeError (argv[idx], "suffix is not numeric");

        switch (chVal) {
            case 'y': nowStr->tm_year = intVal - 1900; break;
            case 'm': nowStr->tm_mon = intVal - 1; break;
            case 'd': nowStr->tm_mday = intVal; break;
        }
    }

    mktime (nowStr);
    strftime (buff, sizeof (buff), "%A, %d %B %Y", nowStr);
    printf ("%s\n", buff);

    return 0;
}

トランスクリプトの例:

pax> ./dow
Tuesday, 09 October 2012

pax> ./dow -y2011
Sunday, 09 October 2011

pax> ./dow -y2000 -m1 -d1
Saturday, 01 January 2000
于 2012-10-09T02:31:12.343 に答える
1

最も可能性の高い説明は、曜日を印刷するように要求する場合、意味のある値がstrftime必要であるということです。tm_wday

これは、自分で計算する必要を回避する最も簡単な方法です。

struct tm tm;

memset(&tm, 0, sizeof(struct tm));
tm.tm_mday = Cur_Day;
tm.tm_mon = Cur_Month - 1;
tm.tm_year = entries[i].Year_Start - 1900;
tm.tm_hour = 12;

(void) timegm(&tm); /* fills in the rest of `tm` as a side effect */

/* now call strftime */

持っていない場合は、代わりtimegmに使用して回避できる場合があります (「ローカル」時間でこの計算を行う際の問題は、日付mktimeのみを印刷する場合はほとんど関係ありません)。の Linux マンページに記載されている「 のポータブル バージョン 」は使用しないでください。ほぼすべての行で移植性の問題が待ち受けています。timegmtimegm

于 2012-10-09T02:32:30.233 に答える
0

変換できるstr_time.tm_wdayように設定する必要があります。strftime()

例については、 localtime(3)およびstrftime(3)を参照してください。

于 2012-10-09T02:30:09.473 に答える