128

TIMESTAMP を使用して日付と時刻を格納しようと考えていましたが、2038 年の制限があると読みました。まとめて質問するのではなく、初心者でも簡単に理解できるように、細かく分割することを好みました。だから私の質問:

  1. 2038年問題とは一体何なのか?
  2. なぜ発生し、発生するとどうなるのですか?
  3. どうすれば解決できますか?
  4. 同様の問題を引き起こさない、それを使用する代替手段はありますか?
  5. TIMESTAMP を使用する既存のアプリケーションに対して、いわゆる問題が実際に発生したときに回避するにはどうすればよいでしょうか?

前もって感謝します。

4

6 に答える 6

165

これをコミュニティ wiki としてマークしたので、自由に編集してください。

2038年問題とは一体何なのか?

「2038 年問題 (Unix ミレニアム バグ、Y2K 問題に類推して Y2K38 としても知られています) は、2038 年以前または 2038 年に一部のコンピューター ソフトウェアに障害を引き起こす可能性があります。この問題は、システム時刻を符号付き 32 として保存するすべてのソフトウェアとシステムに影響します。 -ビット整数で、この数値を 1970 年 1 月 1 日の 00:00:00 UTC からの秒数として解釈します。"


なぜ発生し、発生するとどうなるのですか?

2038 年 1 月 19 日火曜日の 03:14:07 UTCを超える時間は「折り返し」、負の数として内部的に保存されます。これらのシステムは、2038 年ではなく 1901 年 12 月 13 日の時間として解釈します。 UNIX エポック (1970 年 1 月 1 日 00:00:00 GMT) からの秒数が、コンピューターの 32 ビット符号付き整数の最大値を超えるという事実。


どうすれば解決できますか?

  • long データ型を使用する (64 ビットで十分)
  • MySQL (または MariaDB) の場合、時間情報が必要ない場合は、DATE列タイプの使用を検討してください。より高い精度が必要な場合は、DATETIMEではなくを使用してくださいTIMESTAMP。列にはタイムゾーンに関する情報が保存されないことに注意してDATETIMEください。そのため、アプリケーションはどのタイムゾーンが使用されたかを知る必要があります。
  • ウィキペディアに記載されているその他の可能な解決策
  • MySQL 開発者が10 年以上前に報告されたこのバグを修正するのを待ちます。

同様の問題を引き起こさない、それを使用する代替手段はありますか?

データベースに日付を格納するために可能な限り大きな型を使用するようにしてください。64 ビットで十分です。GNU C と POSIX/SuS、またはsprintf('%u'...)PHP または BCmath 拡張機能の long long 型です。


まだ 2038 年ではありませんが、壊れる可能性のあるユース ケースにはどのようなものがありますか?

したがって、MySQL DATETIMEの範囲は 1000 ~ 9999 ですが、TIMESTAMP の範囲は 1970 ~ 2038 のみです。あなたのシステムが生年月日、将来の将来の日付 (例えば 30 年の住宅ローン) などを保存している場合、すでにこのバグに遭遇することになります。繰り返しますが、これが問題になる場合は TIMESTAMP を使用しないでください。


TIMESTAMP を使用する既存のアプリケーションに対して、いわゆる問題が実際に発生したときに回避するにはどうすればよいでしょうか?

2038 年になっても残っている PHP アプリケーションはほとんどありませんが、Web はまだほとんどレガシー プラットフォームではないため、予測するのは困難です。

に変換するデータベース テーブルの列を変更するプロセスを次に示しTIMESTAMPますDATETIME。一時的な列を作成することから始めます。

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

資力

于 2010-01-06T11:41:31.623 に答える
15

UNIX タイムスタンプを使用して日付を保存する場合、実際には 1970-01-01 からの秒数を保持する 32 ビット整数を使用しています。Unix 時間を参照してください

その 32 ビット数は 2038 年にオーバーフローします。それが 2038 年問題です。


この問題を解決するには、日付を格納するために 32 ビットの UNIX タイムスタンプを使用しないでください。つまり、MySQL を使用する場合は を使用しTIMESTAMPないでDATETIMEください

このDATETIMEタイプは、日付と時刻の両方の情報を含む値が必要な場合に使用されます。サポートされる範囲は'1000-01-01 00:00:00''9999-12-31 23:59:59'です。

データ型のTIMESTAMP範囲は'1970-01-01 00:00:01'UTC から '2038-01-19 03:14:07'UTC です。


その問題を回避/修正するためにアプリケーションでできる(おそらく)TIMESTAMP最善の方法は、を使用しないことDATETIMEですが、1970 から 2038 の間ではない日付を含める必要がある列に対してです。

ただし、1 つの小さな注意: (統計的に言えば)非常に高い確率で、アプリケーションは 2038 年までにかなりの回数書き直されている可能性があります ^^ したがって、将来の日付を処理する必要がなければ、おそらく、アプリケーションの現在のバージョンでその問題を処理する必要はありません...

于 2010-01-06T11:41:05.190 に答える
7

Googleで簡単に検索すると、2038年問題が解決します

  1. 2038 年問題 (Unix ミレニアム バグ、Y2K 問題に類推して Y2K38 とも呼ばれます) により、一部のコンピューター ソフトウェアが 2038 年以前または 2038 年に失敗する可能性があります。
  2. この問題は、システム時間を符号付き 32 ビット整数として保存し、この数値を 1970 年 1 月 1 日の 00:00:00 UTC からの秒数として解釈するすべてのソフトウェアとシステムに影響します。 2038 年 1 月 19 日火曜日の 03:14:07 UTC です。この時点を超える時間は「ラップアラウンド」し、負の数として内部的に保存されます。これらのシステムは、2038 年ではなく 1901 年の日付として解釈します。
  3. 既存の CPU/OS の組み合わせ、既存のファイル システム、または既存のバイナリ データ形式の場合、この問題を簡単に修正することはできません。
于 2010-01-06T11:41:35.040 に答える
2

http://en.wikipedia.org/wiki/Year_2038_problemにはほとんどの詳細があります

要約すれば:

1) + 2) 問題は、多くのシステムが日付情報を 1970 年 1 月 1 日からの秒数に等しい 32 ビットの符号付き整数として保存することです。このように保存できる最新の日付は、2038 年 1 月 19 日火曜日の 03:14:07 UTC です。これが発生すると、int は「ラップアラウンド」し、1901 年の日付として解釈される負の数として保存されます。正確に何が起こるかは、システムによって異なりますが、おそらくどのシステムにとっても良くないと言えば十分です!

過去の日付のみを保存するシステムの場合、しばらくは心配する必要はないと思います! 主な問題は、将来の日付を扱うシステムにあります。システムが 28 年先の日付で動作する必要がある場合は、今すぐ心配する必要があります。

3) 利用可能な代替日付形式のいずれかを使用するか、64 ビット システムに移行して 64 ビット整数を使用します。または、データベースの場合は別のタイム スタンプ形式を使用します (たとえば、MySQL の場合は DATETIME を使用します)。

4) 3を参照してください!

5) 4を参照してください!!! ;)

于 2010-01-06T11:51:48.843 に答える
1

ブラザーズ、PHP を使用してタイムスタンプを表示する必要がある場合、これは UNIX_TIMESTAMP 形式から変更しない最適な PHP ソリューションです。

custom_date() 関数を使用します。その中で、DateTime を使用します。これが DateTime ソリューションです。

データベースのタイムスタンプとして UNSIGNED BIGINT(8) がある限り。PHP 5.2.0 ++を持っている限り

于 2010-10-12T21:33:17.173 に答える