web-dev-qa-db-ja.com

UTC ISO8601の日付をMySQLデータベースに保存するにはどうすればよいですか?

私は次の形式で何千もの日付を持っています:

_2011-10-02T23:25:42Z_(UTCでは別名ISO 8601)

このようなISO8601日付をMySQLデータベースに保存するには、どのMySQLデータ型を使用する必要がありますか?例えば。 Datetimetimestampまたは他の何か?

比較(たとえば、2つの日付/時刻間のレコードの取得)とクエリからの結果の順序付けに最適なのはどれですか?データベースが非常に大きい場合はどうでしょうか。

そして、上記のPHP文字列をMySQLストレージ用に変換する最良の方法は何でしょうか?(date_default_timezone_set('UTC');が使用されると思いますか?)

24
user967144

タイプDATETIMEのフィールドに日時値を保持するのは自然な方法だと思います。

私自身の現在のPHPアプリケーションでの経験から、この情報に関するread/write操作のみが問題になる可能性があります。

プロセス全体を適切に実行するための可能な解決策の1つ(DATETIMEデータ型を使用すると仮定)は、次のアプローチである可能性があります。

PHP useのDATETIME値の読み取り

  1. データベースからDATETIMEフィールドを取得してクエリ内'2011-10-02T23:25:42Z'MySQL関数とDATE_FORMATフォーマット文字列を使用して'%Y-%m-%dT%H:%i:%sZ'の形式の文字列表現に変換します(DATE_FORMATのドキュメント
  2. フェッチされた列の値をこの特定の形式で読み取り、PHP文字列からPHP(DateTimeクラスオブジェクトやDateTime::createFromFormatなど)に有効な実際の日時表現に変換します。 'Y-m-d\TH:i:s\Z'フォーマット文字列が指定された静的メソッド(TおよびZは、フォーマットディレクティブとして扱われないようにエスケープされます)(メソッドのドキュメント)。
  3. 変換された値を実際の日時値として使用し、実際の日付の比較(テキスト比較ではない)など、適用可能なすべてのロジックを使用します。

MySQLデータベースへのPHP日時の書き込み

  1. Ie PHP DateTimeクラスオブジェクトを以前と同じDateTimeクラスオブジェクトのformatメソッドを使用してUTC形式の文字列表現でISO8601に変換します'Y-m-d\TH:i:s\Z'フォーマット文字列(documentation =)。
  2. MySQL関数STR_TO_DATE'%Y-%m-%dT%H:%i:%sZ'フォーマット文字列を使用)のパラメーターとして準備された文字列を使用して、データベース情報に対してINSERT/UPDATE操作を実行します。これにより、実際のデータベースDATETIME値(STR_TO_DATEのドキュメント =)。

PHPのサンプルコード

以下に、PDOオブジェクトを使用したこのようなアプローチのドラフト例を示します。

$db = new PDO('mysql:Host=localhost;dbname=my_db;charset=utf8', 'username', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    // run the query aquring 1 example row with DATETIME data 
    // converted with MySQL DATE_FORMAT function to its string representation 
    // in the chosen format (in our case: ISO 8601 / UTC)
    $stmt = $db->query("SELECT DATE_FORMAT(dt_column, '%Y-%m-%dT%H:%i:%sZ') AS formatted_dt_col"
                        ." FROM your_table LIMIT 1"); 

    if($stmt !== FALSE) {
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        // convert the acquired string representation from DB 
        // (i.e. '2011-10-02T23:25:42Z' )
        // to PHP DateTime object which has all the logic of date-time manipulation:    
        $dateTimeObject = DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $row['formatted_dt_col']);

        // the following should print i.e. 2011-10-02T23:25:42Z
        echo $dateTimeObject->format('Y-m-d\TH:i:s\Z');  

        // now let's write PHP DateTime class object '$dateTimeObject' 
        // back to the database
        $stmtInsertDT = $db->prepare("INSERT INTO your_table(dt_column) " 
                             . " VALUES ( STR_TO_DATE(:par_formatted_dt_column, '%Y-%m-%dT%H:%i:%sZ') )");

        $dtAsTextForInsert = $dateTimeObject->format('Y-m-d\TH:i:s\Z');

        // convert '$dateTimeObject' to its ISO 8601 / UTC text represantation
        // in order to be able to put in in the query using PDO text parameter
        $stmtInsertDT->bindParam(':par_formatted_dt_column', $dtAsTextForInsert, PDO::PARAM_STR);

        $stmtInsertDT->execute();

        // So the real insert query being perform would be i.e.:
        /*
           INSERT INTO your_table(dt_column) 
           VALUES ( STR_TO_DATE('2011-10-02T23:25:42Z', '%Y-%m-%dT%H:%i:%sZ') )
        */
    }
}
catch(\PDOException $pexc) {
 // serve PDOException
}
catch(\Exception $exc) {
// in case of no-PDOException, serve general exception
}

このアプローチは、PHPとMySQLデータベースの間の日時値を操作するのに大いに役立ちました。

それがあなたにも役立つことを願っています。

16
user2941651

日付と時刻を格納するためにDateTimeデータ型を使用できます。

CAST関数を使用して、そのような文字列をmysql DateTime型にキャストします。

次に例を示します。

CAST("2011-10-02T23:25:42Z" AS DATETIME)

これにより、2011-10-02 23:25:42が得られます。

これがお役に立てば幸いです。

11
Ashish Awasthi

strtotimephp関数を使用して、日付を簡単に変換できます。

date_default_timezone_set('UTC');
$date = '2011-10-02T23:25:42Z';//(aka ISO 8601 in UTC)
$time = strtotime($date); //time is now equals to the timestamp
$converted = date('l, F jS Y \a\t g:ia', $time); //convert to date if you prefer, credit to Marc B for the parameters

これで、ニーズに最も合うものに応じて、MySQLまたはtimestampを使用してdatetimeに日付を挿入するだけです。ここでは、両方のタイプについて知っておくべき最も重要なことを説明します。


タイムスタンプ

  • '1970-01-01 00:00:01'UTCから' 2038-01-09 03:14:07'UTCの範囲
  • タイムゾーン設定の影響を受けます。
  • 4バイトのストレージ
  • すべてのバージョンの列でon update current_timestampを許可します。
  • インデックスははるかに高速です
  • NULLは可能なデフォルト値ではありません
  • 値は、保存のために現在のタイムゾーンからUTCに変換され、取得のためにUTCから現在のタイムゾーンに変換されます。

日時

  • '1000-01-0100:00:00'から '9999-12-3123:59:59'の範囲
  • 一定(タイムゾーンは影響しません)
  • 8バイトのストレージ
  • バージョン5.6.5の時点でのみ列の更新を許可する

比較(たとえば、2つの日付/時刻間のレコードの取得)とクエリからの結果の順序付けに最適なのはどれですか?データベースが非常に大きい場合はどうでしょうか。

前に述べたように、ストレージが小さいため、非常に大きなデータベースにはtimestampを使用する必要があります。インデックスが高速であるため、比較のパフォーマンスが向上します。ただし、必ず日付が前述のtimestampの制限に適合することを確認してください。そうでない場合は、選択の余地がなく、datetimeを使用する必要があります。 。

strtotimeのドキュメント: http://php.net/manual/en/function.strtotime.php

そして、mysql*[〜#〜]非推奨[〜#〜]関数を使用しないように毎日繰り返し続けるSOの回答者のために、使用してください挿入を行う場合は、PDOまたはmysqli*

http://php.net/manual/en/book.pdo.php

http://php.net/manual/en/book.mysqli.php

日付を生のUTCISO8601形式で保存することはできません(2011-10-02T23:25:42Z表現)そしてすべてのSQLDATETIME機能を保存します。

ただし、MySQL( http://dev.mysql.com/doc/refman/5.5/en/datetime.html に関して)は常に時刻/日付をUTCで保存することを知っておく必要があります。また、接続のタイムゾーンを変更することもできます http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

したがって、PHPで実行する場合

date_default_timezone_set('UTC');

そしてMySQLでは

SET time_zone = +00:00

確かにPHPそしてMySQLはUTCを使用します。

その後、タイムゾーンの不一致を気にすることなく、すべてのデータベース文字列をDateTimeに変換できます。

PHP DateTime(内部タイムゾーンを持ち越さない)をMySQLの日時文字列に変換するには、DateTimeオブジェクトのタイムゾーンをUTCに設定する必要があります。

$datetime->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s');
2
Electronick

PDTである私のシステムであなたの日時を使用する:

SELECT CONVERT_TZ(str_to_date('2011-10-02T23:25:42Z','%Y-%m-%dT%H:%i:%sZ'),'+00:00','SYSTEM') from dual;

2011-10-02 16:25:42

日時のマイクロ秒が小数部の場合。次のように、Zの前に。%fを含めます。

SELECT CONVERT_TZ(str_to_date('2011-10-02T23:25:42.123456Z','%Y-%m-%dT%H:%i:%s.%fZ'),'+00:00','SYSTEM') from dual;

2011-10-02 16:25:42.123456
1
CraigC

日時を使用する方がよい理由は次のとおりです。

  1. Datetimeを使用すると、mysql側で日付操作(日、月の減算など)を実行できるようになります。
  2. データを並べ替えることができます。
  3. DBが巨大な場合-varcharはHDDでより多く発生します
0
Gfox