明示的に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