6

以下のCコードを使用して、2つの日付の違いを取得しようとしています。

しかし、コードは常に差0を与えます。間違いを犯している場所を教えてください。

Linuxでgccコンパイラを使用しています。

#include <stdio.h>  
#include <time.h>       
int main ()
{
  struct tm start_date;
  struct tm end_date;
  time_t start_time, end_time;
  double seconds;

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 2013;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 2013;

  start_time = mktime(&start_date);
  end_time = mktime(&end_date);

  seconds = difftime(end_time, start_time);

  printf ("%.f seconds difference\n", seconds);

  return 0;
}

編集: @qchenの回答は、私の問題を解決するのに大いに役立ちました。もう1つ疑問があります。以下は私の更新でした。答えから

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10-1; start_date.tm_mday = 18; start_date.tm_year = 2013-1876;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10-1; end_date.tm_mday = 20; end_date.tm_year = 2013-1876;

tm_year は 1900 年以降の年です。1876 年を 1876 年から 2012 年までの年に置き換えると、なぜ正しい出力が得られるのでしょうか。

4

3 に答える 3

3

問題は、tm_year が 1900 年以降の年であるため、2013 年は 113 http://en.cppreference.com/w/cpp/chrono/c/tmになることです。

  start_date.tm_hour = 0;  start_date.tm_min = 0;  start_date.tm_sec = 0;
  start_date.tm_mon = 10; start_date.tm_mday = 15; start_date.tm_year = 113;

  end_date.tm_hour = 0;  end_date.tm_min = 0;  end_date.tm_sec = 0;
  end_date.tm_mon = 10; end_date.tm_mday = 20; end_date.tm_year = 113;

2013 年の場合、暦時間を表すことができないため、mktime は -1 を返します。3913 年が有効な暦時間であり、その理由はJoni が指摘した2038 年の問題に関連していると考えるでしょう。

于 2013-09-26T18:40:14.503 に答える
1

OP は mktime()` の結果をチェックしませんでした。

@Joni が言及しているように、tm_isdstフィールドを設定します。DST の適用方法がわかっている場合は0orを使用し、それ以外の場合は「-1」を使用して OS に判断させます。1

@qchen は、1900 年のオフセットについて言及しました .tm_year = 2013-1900

根本的な問題はmktime()、それが(time_t) -1. 堅牢なコードでは、この戻り値をテストし、 OP コード開いたときに予期しない結果が発生しないようにする必要があります。

于 2013-09-26T19:41:01.940 に答える
0

年を正しく指定しないことに加えて、tm_isdstフィールドを未設定のままにしています。mktimeこのフィールドを使用して、日付に夏時間が有効かどうか、または DST 設定をタイムゾーン データベースから検索する必要があるかどうかを判断します。これにより、結果が 1 時間ずれることがあります。次の行を追加します。

/* lookup if DST or not */
start_date.tm_isdst = -1;
end_date.tm_isdst = -1;
于 2013-09-26T18:56:27.530 に答える