• 締切済み

初級者の質問――time_tについて

私はC言語の初級者です。 time関数というのは現在時刻をtime_t型で返すものですよね。 でも、私はこの意味がよくわかりません。 time_t型とは何でしょうか。 単なる整数なのでしょうか。 確か、time_t型というのは整数で、 1970年1月1日0時からの秒数(世界標準時)だと聞いた気がします。 しかし、(いくつか見てみましたが)大抵のC言語の本では、そういう説明はしていません。 「プログラミング言語C」(カーニハン、リッチー)という本では、 「timeは現在のカレンダー時間を返す。」 と説明しています。 「じゃあ、カレンダー時間って何?」と思いますが、「カレンダー時間」というものの説明は見当たりません。 time_tというのは整数と考えてよいのでしょうか。 time_tで変数宣言すると、プログラムを読む人が「あ、これは時間を表すんだな」とわかり易いから、time_tというものがあるのでしょうか。 それとも、 time_tが秒数を表すかどうかは処理系に依存するのでしょうか。 もし、1970年1月1日からの秒数を表すなら、time関数の戻り値を1年間の秒数で割って1970に足せば今何年かわかるプログラムになりそうですよね。(うるう年や時差は考慮する) それとも、それは処理系によっては正しく動かないプログラムになるのでしょうか。 (あくまでも考え方です。確か、time_tを渡せば年月日時分秒を返す関数があると思います。) ちなみに、おとといプログラムを作ってtime関数の戻り値を10進数で表示すると次のようになりました。(VC++) ==============プログラム============== #include <stdio.h> #include <time.h> int main(void) { time_t a; a=time(NULL); printf("%d\n",a); return(0); } ================結果=============== 1005300371

みんなの回答

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.7

> C99とは、ISOの規格で比較的新しいものと思います。 そうです。 正式にはISO/IEC 9899:1999です。 > (C98というのは知りませんでした。) 失礼しました。 C89の間違いです。 同様にISO/IEC 9899:1989です。 > しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか 時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。 また、「1970年1月1日0時0分0秒からの経過秒数」というのは慣例に過ぎません。 とはいえ、UNIXを起源とする『time_tはlong』と『time()は1970年1月1日0時0分0秒からの経過秒数』という約束事は変えられる事は無いでしょう。 C98/C89との互換性を保ちながら新規格を作ることが予想されるからです(そうでなければlong longなどという型は作らないはず)。 その意味でyoushirさんのおっしゃるとおりだと思います。

noname#1254
質問者

お礼

>時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。 ということは、C言語の本で time関数はいついつからの秒数を返します、 などと書かない理由は自明ですね。 (No.6の回答より) >ANSI-Cにおいて「time_tは整数値」という規定があります。 time_tが整数値でなくてはいけないのか(time_tがdoubleでも規格に反しないのか)という点まで突っ込んで考えればきりはないですが、 私のような初級者がそこまで知る必要もないでしょう。 (質問から) >それとも、それは処理系によっては正しく動かないプログラムになるのでしょうか。 そういう可能性があるということですね。

noname#1254
質問者

補足

(締め切る前に―――ここの回答とは直接の関係はないですが) time関数は、失敗したとき(無効の場合)、 (time_t)-1、つまり、time_tでキャストした-1 を返します。 (質問は規格に関するものですが、規格のことは置いておいて。) 戻り値が負の数である可能性があることを考えると、time関数の戻り値の型は、 符号付きの型になっているのが自然のように思われます。 (キャストすれば何でもいいだろう、という考えは、確かにそれはそうですが。)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.6

ANSI-Cにおいて「time_tは整数値」という規定があります。 よってC98ではshortまたはlong、C99ではshort/longまたはlong longのいずれかとなります。

noname#1254
質問者

補足

ご回答ありがとうございます。 わたしの知識が正しいか、自信がないですが… C99とは、ISOの規格で比較的新しいものと思います。 (C98というのは知りませんでした。) 今、私の手元に『新ANSI C言語辞典』(技術評論社)という本があるのですが、それによると、 ・time_tは算術型である。 ・算術型とは、汎整数型と浮動小数点型の総称。 ということがわかりました。 ご回答に照らしても、 「time_tが構造体であっても、 問題ないわけですね」(#4補足)なる私の発言は暴論であることがわかります。(ANSI C の場合。) しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか(ANSI C の場合)。(もしかして、これも暴論かもしれません。) こういうことは言えませんか? time_t型が1970年1月1日0時からの秒数だと規格で決まっているならば、time関数の戻り値の説明をするときに、 戻り値はカレンダー時間(暦時間)である、 などと奥歯にものの挟まったような言い方をしないで、素直に「1970年1月1日0時からの秒数」だと言えばよいと思いませんか?

  • ykkw_2001
  • ベストアンサー率26% (267/1014)
回答No.5

こんにちは、 >時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、time_tが構造体であっても、 >C言語としては問題ないわけですね ? 時間関係は、混乱しやすいですよね。 多分その目的には、tm 構造体というのが適しているように思います。 また、独自の時刻データ型を作る場合は、MyTime_t などのように、他の人にもわかる名前にする事をお勧めします。 確かに自分だけが見る趣味のプログラムなら、「time_tが構造体であっても、C言語としては問題ない」ですけど、他の人が見る仕事関係のプログラムでは、標準(言い換えると常識的)ではない定義があると、他の人はすんごく迷惑します。 少なくとも私の回りでは、そのようなことは「禁止」にしています。「エラーが出ないからOK」とか「このほうが(自分で)わかりやすい」からと好き放題したプログラムのトラブルを直す実力になり、同様の事を経験したら、このことは、実感としてご理解いただけると思います。 (このような「前提が変」という問題だけは、よく泣かされます) 初心者の方ということなので、今後を思いあえて書かせていただきました。

noname#1254
質問者

お礼

ありがとうございます。

  • brogie
  • ベストアンサー率33% (131/392)
回答No.4

小生はC++Buiderですが、 time.h を見ますと次のように定義してありました。 typedef long time_t; 以上です.

noname#1254
質問者

補足

ありがとうございます。 私の本来の質問は 「C言語と呼ぶにあたって、time_tが整数である必要はあるのか」 という点に質問の重点があったわけですが、 #1の補足で述べましたように、私は 「実際にそのような(整数でない)処理系はあるのでしょうか。 」 ということもあわせて聞いています。 後者に関することとしてお答えいただいたわけですね。C++Buiderもlongだということですね。 参考になります。 皆さんにご確認を取りたいと思います。 time_tが1970年1月1日からの秒数だということはC言語として必須ではなくて、 時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、time_tが構造体であっても、 C言語としては問題ないわけですね ?

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

>time_t型とは何でしょうか。 現在時刻を返すための型です。 intとしないのは、今後、例えば128bit整数が必要になった場合でも, インクルードファイルやライブラリを変えて、コンパイルしなおすだけで対応できるようにするためです。 当然,intでなくても構いませんし,2038年までには変わるだろうとは思います。 32bit整数だと2038年に桁数がたりなくなるからです。 既にそうなっているOSもあるだろうと思います。 もし、intとしてコーディングすると、こういう変更がおきた場合に、ソースコードレベルで修正が必要です。 それも、どこにどの程度あるのか簡単にわかりませんから、手間もかなりかかります。 また、他の環境では現在でも違う可能性がありますから、同じソースを違う環境で動作させるためにも time_t型にしておく必要はあります。

参考URL:
http://member.nifty.ne.jp/shyu/20xx/2038.htm
noname#1254
質問者

お礼

とてもよくわかりました。 「time_tって書いてあると時刻ということがわかり易いから、time_tというのがある」というよりも(そういう側面もありますが。)、 long型では、いちいちソースを見て直さなければいけないため、2038年問題に対処するのが困難だ、ということですね。 2の31乗 = 2,147,483,647秒 = 68年とちょっと・・ (参考URLより。) >他の環境では現在でも違う可能性がありますから、同じソースを違う環境で動作させるためにも >time_t型にしておく必要はあります。 よくわかりました。

noname#9414
noname#9414
回答No.2

補足読みました。 time_tがlong/intでない処理系ということですが、たいていのC言語の環境はANSI C+拡張であることから考えても、まず問題はないと思います。 #手元にANSI Cの環境がないので、何ともいえませんが。 もう少しほかの方の環境も聞いてみてもいいかもしれませんね。 ではでは☆

noname#9414
noname#9414
回答No.1

一応Visual C++ではtime.hの中にtime_tはlongという風に宣言してありますね。 従って、中身は単純なlong型。一応これは対外の環境で問題は出ないと思いますよ。ただ、MSDNにはlong intと書かれているので、int型(longと同等の)と扱われる場合もあるようです。long宣言しておけば問題はないと思います。 まぁ、time_tを使う理由はやはり「みてすぐにわかるから」だと思いますよ。 ではでは☆

noname#1254
質問者

補足

ありがとうございます。 >Visual C++ではtime.hの中にtime_tはlongという風に宣言してありますね。 >time_tを使う理由はやはり「みてすぐにわかるから」だと思いますよ。 Visual C++の場合はわかりました。 そうすると、問題は、Visual C++に限らない「C言語一般」の場合はどうなのか、ということになりますね。 time_tがlongでもintでもない処理系があっても、C言語の規格として問題はないのでしょうか。 また、実際にそのような処理系はあるのでしょうか。 (なお、今私の扱っているコンピュータには、Cどころかプログラミング環境がないので、VC++のこともわかりません。今は。)

関連するQ&A