プロが教える店舗&オフィスのセキュリティ対策術

いつもお世話になっております。
先日、『YYYY/MM/DD』形式から年・月・日を取り出し、整数にする質問をさせて頂き、無事に行うことができました。
ありがとうございます。
再びの質問で恐縮ですが、どうか教えてください。

先日の質問に引き続き、日付の妥当性をチェックする関数を考えています。そこで、「http://f4.aaa.livedoor.jp/~pointc/log453.html」というサイトを見つけたのですが…。
その中で、"20020101"という文字列を『strncat』で分割し、『atoi』してから『tm構造体』へ代入しています。
この『tm構造体』というものがよく分かりません。
調べて見ると、『time()』関数にて取得した暦を『localtime()』関数を使ってローカルタイムに変換し、その値が『tm構造体』となって戻ってくる。というようなことが書いてあります。(正しい理解ができているか、不安なところですが。)
なぜ、『tm構造体』へ代入しただけで、日付を算出できるのでしょうか?『tm構造体』は『localtime』関数の戻り値ではなく、単体で利用できるのでしょうか。他に関数というかライブラリ関数のようなものは見当りません。
『tm構造体』自体が計算か何かをしているのでしょうか?

乱文で申し訳ありません。
どうかご協力お願いいたします。

A 回答 (3件)

自前で日付の妥当性を判定する場合には、あらかじめ適用範囲を明確にする必要があります。

というのも、グレゴリオ暦が採用される時期は、宗教的・政治的な理由から、国によってまちまちだからです。

例えば、グレゴリオ暦ができた頃(1582年)といえば、日本ではちょうど本能寺の変があった頃で、当然旧暦を使っていましたから、グレゴリオ暦のルールで妥当性を判定しても意味がありません。欧米でも、カソリック圏には比較的早く普及しましたが、プロテスタント圏への普及は1世紀以上遅れますし、ギリシャ正教圏がグレゴリオ暦に移行したのは日本より遅かったりします。また、イスラム圏などではそもそも別の暦法を使っています。

比較的最近の年代だけを扱うのか、あるいはロケールに応じて判定方法を変えるのかなど、暦の扱いは結構奥が深いのです。
    • good
    • 0
この回答へのお礼

jacta様
丁寧なご説明をありがとうございます!
『グレゴリオ暦』は世界共通ではないのですね。
"月"や"日"は決まっていますが、"年"の適用範囲は考えてみると本当に難しいです。
今回は最近の年代を扱えばよいと思うので、適用範囲を狭くしようと思います。
ご丁寧に教えていただき、本当にありがとうございました!

お礼日時:2007/02/21 15:41

★自前関数でチェックしてみてはどうでしょうか?


・下にC言語を中心とした小技集のサイトを紹介します。
・下の『指定の年月日が有効であるか判定する』という項目を参考にして下さい。

参考文献:
http://katsura-kotonoha.sakura.ne.jp/prog/c/tip0 …→『年月日から曜日を求める』
http://katsura-kotonoha.sakura.ne.jp/prog/c/tip0 …→『指定の年が閏年かどうか判定する』
http://katsura-kotonoha.sakura.ne.jp/prog/c/tip0 …→『指定の年月日が有効であるか判定する』
http://katsura-kotonoha.sakura.ne.jp/prog/c/tip0 …→『指定の年月日がグレゴリウス歴の範囲内かどうか判定する』

参考URL:http://katsura-kotonoha.sakura.ne.jp/prog/c.shtml
    • good
    • 0
この回答へのお礼

Oh-Orange様
丁寧なご回答をありがとうございます。
早速『指定の年月日が有効であるか判定する』を拝見させていただきました。
『うるう年かどうか判定する』の関数もあり、とても勉強になります。
このような関数を自分で思い付けるようになりたいですが、まだまだ勉強が足りないようです。
これらの関数を使って、早速プログラムを作ってみたいと思います。
本当にありがとうございました。

お礼日時:2007/02/21 13:17

tm構造体へ代入しただけでは日付の妥当性は判定できません。

取り上げられているサイトでは、mktime関数を呼び出すことで妥当性の確認を行おうとしているようですが、mktimeはtm構造体に変な値を格納していても勝手に補正してしまうので、妥当性の判定には使えません。また、日付としては妥当であっても、time_t型の表現範囲を超えていればエラーを返します。例えば、3000年1月1日などは、多くの処理系ではエラーになるはずです。
    • good
    • 0
この回答へのお礼

jacta様
丁寧なご回答をありがとうございます!!
『mktime』という関数を使っているのですね。そんな関数があることも知りませんでした…。
『mktime』は変な値も勝手に補正しているとありますが、確かにそれでは妥当性をチェックできないですね。『mktime』を使う前に何かチェックを入れるべきなのでしょうか?
それとも別に方法があるのでしょうか?

重ねがさねで申し訳ありません。

お礼日時:2007/02/21 11:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!