2012-03-05 12 views
6

私は、年、ユリウス日(年の日)、時、分、および観測という2つの文字列を読みました。私はsscanf関数使用して、関連する変数を引き出すmktime()がtm構造体の年の日を変更するのはなぜですか?

:この特定のデータ・セットの場合は

sscanf(tide_str1.c_str(), "%d %d %d %d %Lf", &y1, &j1, &h1, &m1, &obs1); 
sscanf(tide_str2.c_str(), "%d %d %d %d %Lf", &y2, &j2, &h2, &m2, &obs2); 

を、値が2011 083 23 22 1.1

ている私は、作成および移入tm構造体を、とはmktimeを実行しますその間に叫び声が鳴り、それは083から364に変わる。

int y1=2011, j1=83, h1=23, m1=22; 
struct tm time_struct = {0, 0, 0, 0, 0, 0, 0, 0, 0}, *time_ptr = &time_struct; 
time_t tv_min; 
time_struct.tm_year = y1 - 1900; 
time_struct.tm_yday = j1; 
cout << time_struct.tm_yday << endl; 
time_struct.tm_hour = h1; 
time_struct.tm_min = m1; 
time_struct.tm_isdst = -1; 
cout << time_struct.tm_yday << endl; 
tv_min = mktime(time_ptr); 
cout << time_struct.tm_yday << endl; 

なぜですか?なぜなら、tm_mdayとtm_monは0に設定されているからですか?最初はすべてゼロに初期化しないようにしましたが、mktimeは-1を返しました。月と日ではなく、年の日だけを知っているならば、私はどうやって別のことをしなければなりませんか?

+0

年の日は時々*誤っ*「ユリウス日」と呼ばれています。実際、[Julian Day](http://en.wikipedia.org/wiki/Julian_day)の数字は、4713年1月1日からの紀元前の日数です。それは天文学で使用されています。 –

+0

はい、しかし、それは実際には正確であるために、特定の職業内で広く(誤って)使用されています。フィールド内の誰もが同じジャージンを使用している限り、コミュニケーションは起こります。 – RuQu

答えて

13

mktime()これはやりたいことです。 C規格を引用

はmktime機能が破壊ダウンタイムを変換は、構造において、 ローカル時間として表現とカレンダ 時間値にによってtimeptr指さ によって返された値と同じエンコーディング時間の機能です。 tm_wdayおよび tm_ydayの元の値は無視され、他のコンポーネントの元の値は上記の範囲 に限定されません。正常に完了し、 tm_wdayコンポーネント及び構造のtm_yday成分の値が適切に設定され、そして他の構成要素は、しかし上に示した範囲 に強制それらの値と、 指定されたカレンダー時間を表すように設定されています。 tm_mdayの最終値は、まで設定されません。tm_mon およびtm_yearが決定されます。

mktime()他のメンバーからtm_mdaytm_yday値を計算することができます。それらのフィールドから他のメンバの値を計算するようには設計されていません。

ただし、できることは範囲外の値でstruct tmを初期化しています。たとえば、tm_ydayを200(年の200日目)にする場合は、1月の200日を表すstruct tmを初期化できます。 mktime()はそれを正しい日付に正規化し、の値を返します。gmtime()またはlocaltime()にフィードできます。ここで

は簡単な例です:

#include <iostream> 
#include <ctime> 

int main() 
{ 
    struct tm t = { 0 }; 
    t.tm_sec = t.tm_min = t.tm_hour = 0; // midnight 
    t.tm_mon = 0;      // January 
    t.tm_year = 2012 - 1900; 
    t.tm_isdst = -1;      // unknown 

    t.tm_mday = 200;      // January 200th? 

    time_t when = mktime(&t); 
    const struct tm *norm = localtime(&when); // Normalized time 

    std::cout << "month=" << norm->tm_mon << ", day=" << norm->tm_mday << "\n"; 
    std::cout << "The 200th day of 2012 starts " << asctime(norm); 
} 

出力は次のようになります。

month=6, day=18 
The 200th day of 2012 starts Wed Jul 18 00:00:00 2012 
+0

私はあなたのアドバイスを試み、このように初期化しました:struct tm time_struct = {0、0、0、200、200、0、200、0、0}これは前から364に近いが、それでもなおオフである。 – RuQu

+1

標準では 'struct tm'のメンバの順序を保証していないので、それを初期化することは必ずしも機能しません。すべてのメンバーを名前で初期化または割り当てる必要があります。しかし、通常の順序で宣言されている場合は、 'tm_mday'と' tm_mon'を200に初期化しています.200年代、つまり201日目を希望しません。 (そして、 'struct tm'は月に0から11までの数字で、1から12までではないことを忘れないでください。) –

+0

私は年の日が83になるようにするには、月を0に、月の日を83? – RuQu

関連する問題