PHP と mySQL:2038 年のバグ:それは何ですか?どうやって解決すればいいでしょうか?

StackOverflow https://stackoverflow.com/questions/2012589

  •  19-09-2019
  •  | 
  •  

質問

TIMESTAMP を使用して日付 + 時刻を保存することを考えていましたが、2038 年の制限があると読みました。まとめて質問するのではなく、初心者ユーザーにも理解しやすいように、質問をいくつかの部分に分割することを好みました。そこで私の質問:

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

前もって感謝します。

役に立ちましたか?

解決

が付いているこのコミュニティのwikiでお気軽に編集す。

これは、2038年問題なのか。

"は、2038年問題としても知られるUnixのミレニアムの不具合にY2K38類推によって、Y2K問題)であることからコンピュータソフトウェアが前年2038.この問題に影響するすべてのソフトウェア-システム内カンパニーのヘルスケアシステムとして符号付き32ビット整数と解釈するこ数として数秒から00:00:00UTC月1,1970."


なぜで発生したときに何が生じるか

時代を超えて 03:14:07JST日(火)、19日2038 今'ッ'とすると、内部に格納されますし、負の数は、これらのシステムとして解釈し、時間月13日には、1901年による2038.このように数秒からのUNIX時代(1 1970年00:00:00GMT)の値を超えてコンピュータの最大値を32ビット符号付き整数.


どうしてを解くのですか?

  • 用するデータタイプ(64ビットが十分)
  • のためにはMySQLまたは変更する場合に必要な期間情報の利用を考える DATE カラムタイプです。が必要な場合はより精度の高い利用 DATETIMETIMESTAMP.ょう DATETIME 柱のない店舗に関する情報のタイムゾーンで申請しているタイムゾーンを使いました。
  • その他の解決策に記載のWikipedia
  • お待ちMySQL♪修正 このバグ られた。

が可能な代替案を用いないポーズ同様の問題なのか。

みどこでも使用可能で大型収納用の写真データベース:64ビットが十分に長い長いタイプのGNU CとPOSIX/SuS、 sprintf('%u'...) PHPのBCmathいます。


どう考えている可能性の破れの場合に使いたしましたとおりについて2038?

でMySQL DATETIME の1000-9999がタイムスタンプのみの1970-2038.システムの場合、店舗の生年月日、今後の前日など30年の住宅ローン)、または類似のだっ走るこのバグ。再利用がないのタイムスタンプの場合は問題です。


自分たちにしかできないのは、既存のアプリケーションを使用するタイムスタンプのため、いわゆる問題が本当に生じるか

数PHPの用途が回2038が難しい見通しとしてウェブなどのレガシィ-プラットフォームます。

ここではプロセスの変更をデータベーステーブルの列への変換 TIMESTAMPDATETIME.くなり、その作成の臨時列:

# 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`

資源

他のヒント

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

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


この問題を解決するには、日付の保存に 32 ビットの UNIX タイムスタンプを使用しないでください。つまり、MySQL を使用する場合は、 TIMESTAMP, 、 しかし DATETIME (見る 10.3.1.DATETIME、DATE、および TIMESTAMP 型) :

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 年までに何度も書き直されることになります ^^ したがって、将来の日付を扱う必要がなければ、現在のバージョンでその問題に対処する必要がなくなるかもしれません。あなたのアプリケーションの...

Aクイック検索にGoogleのだという: 2038年問題

  1. 年2038問題としても知られるUnixのミレニアムの不具合にY2K38類推によって、Y2K問題)であることからコンピュータソフトウェアが前年2038
  2. この問題に影響するすべてのソフトウェア-システム内カンパニーのヘルスケアシステムとして符号付き32ビット整数と解釈するこ数として数秒から00:00:00UTC月1,1970年.最新の時刻表すことができるこの方は03:14:07JST日(火)、19日2038.時代を超えて今この瞬間まで"ラップ"する、内部に格納されますし、負の数は、これらのシステムとして解釈し、日1901年よ2038
  3. あることは容易ではありませ修正のためにこの問題のための既存のCPU/OSの組み合わせ、既存のファイルシステム、または既存のバイナリデータ形式

http://en.wikipedia.org/wiki/Year_2038_problemするのほとんどを持っています詳細

要約ます:

1)+ 2)の問題は、1970年1月1日からの秒数に等しい32ビット符号付き整数として、多くのシステムストアの日付情報です。これは、INTを発生すると、これは火曜日の午前3時14分07秒UTCであるように保存することができる最新の日付は、2038年1月19日には「ラップアラウンド」になり、1901年に日付として解釈されます負の数として格納されます。まさに、その後何が起こるか、システムによって異なりますが、それはおそらくそれらのいずれかのために良いことではないだろうと言うことで十分!

だけ過去に日付を格納システムでは、その後、私はあなたがしばらくの間、心配する必要はありませんね!主な問題は、将来の日付で動作するシステムです。お使いのシステムは、将来的には28年の日付で作業する必要がある場合、あなたが今気に開始する必要があります!

3)利用可能な代替日付形式のいずれかを使用または64ビットのシステムに移動し、64ビットのintを使用します。またはデータベースのための

代替タイム・スタンプ・フォーマット(MySQLはDATETIMEを使用するためなど)を使用します

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

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

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

CUSTOM_DATE()関数を使用します。その中に、日時を使用します。 ここでのDateTimeソリューションです。

限り、あなたは、データベース内の自分のタイムスタンプとしてUNSIGNED BIGINT(8)を持っているとして。 限り、あなたはPHP 5.2.0を持っているよう++

私は何をアップグレードしたいdid'tとして

、私の代わりにPHPのこの仕事をするために私のバックエンド(MSSQL)を尋ねた!

$qry = "select DATEADD(month, 1, :date) next_date ";
$rs_tmp = $pdo->prepare($qry);
$rs_tmp->bindValue(":date", '2038/01/15');
$rs_tmp->execute();
$row_tmp = $rs_tmp->fetch(PDO::FETCH_ASSOC);

echo $row_tmp['next_date'];

効率的な方法であるが、それが動作できない場合があります。

scroll top