Home / ぼやきごと / 2021-04-21 / VC++:3001年問題
VC++:3001年問題

[前へ] [次へ] [目次]

VC++:3001年問題

2000年問題も気付けば20年以上前で、2038年問題が近付いてきている今日この頃ですが、今回は3001年問題のお話です。
3001年問題や、その前身の3000年問題については下記のサイトを参照してください。

簡単に言うと、 time_t 型自体は 64 ビットあり2000億年以上を扱えるのに*1、 Visual C++ の時間関数群の実装ではなぜか 3001 年以降を扱えないようにキャップされてしまっているという問題です。
キャップ無しだとそれはそれでセキュリティ上問題がありそうですが、それにしたってもう少し大きい値でキャップしてもいいような気がしますね。

そんな3001年問題ですが、具体的に各関数の引数値の許容範囲を調べてみたところ、使用する関数やVC++のバージョンによって値に差があることがわかりました。
私が調べたのは2012、2013、2015、2017、2019ですが、2013以前と2015以降で変化があったようです。

time_t 値を引数にとり tm 構造体値を作成する関数
関数VC++バージョン引数値の許容範囲備考
最小最大
gmtime, gmtime_s2012, 2013-4320032535291599作成値は 1969/12/31 12:00:00 〜 3001/01/01 20:59:59
2015, 2017, 2019-4320032536850399作成値は 1969/12/31 12:00:00 〜 3001/01/19 21:59:59
localtime, localtime_s2012, 2013032535244799作成値は 1970/01/01 00:00:00 〜 3001/01/01 07:59:59 (UTC換算)
2015, 2017, 2019032536799999作成値は 1970/01/01 00:00:00 〜 3001/01/19 07:59:59 (UTC換算)
tm 構造体値を引数にとり time_t 値を作成する関数
関数VC++バージョン引数値の許容範囲(UTC換算)備考
最小最大
_mkgmtime2012, 20131969/12/31 12:00:003001/01/01 20:59:59作成値は -43200 〜 32535291599
2015, 2017, 20191969/12/31 12:00:003001/01/19 21:59:59作成値は -43200 〜 32536850399
mktime2012, 20131970/01/01 00:00:003001/01/01 07:59:59作成値は 0 〜 32535244799
2015, 2017, 20191970/01/01 00:00:003001/01/19 07:59:59作成値は 0 〜 32536799999

mktime の最小/最大許容値はUTC換算なので、例えば日本のタイムゾーン(UTC+9)で利用する場合、それぞれ9時間ずつ足した値が実際の許容範囲になります。

確認した限りだと、UTCベースの関数とローカルベースの関数でぞれぞれ同じ許容範囲となっているようです。
ただ、どうしてこの値でキャップしているのか、どうしてVC++2015で最大許容値が変更されたのかといった理由は結果だけ見てもわかりませんでした。

個人的には、 gmtime, gmtime_s の time_t 引数値に、最大12時間までとはいえマイナスの値を指定できることに驚きました。

Category: [C++][Visual Studio][プログラミング] - 2021-04-21 00:39:00

[前へ] [次へ] [目次]

*1 tm 構造体の tm_year メンバが int 型なので約 21 億年までしか扱えないという問題があったりしますが…。