私は次の形式で何千もの日付を持っています:
_2011-10-02T23:25:42Z
_(UTCでは別名ISO 8601)
このようなISO8601日付をMySQLデータベースに保存するには、どのMySQLデータ型を使用する必要がありますか?例えば。 Datetime
、timestamp
または他の何か?
比較(たとえば、2つの日付/時刻間のレコードの取得)とクエリからの結果の順序付けに最適なのはどれですか?データベースが非常に大きい場合はどうでしょうか。
そして、上記のPHP文字列をMySQLストレージ用に変換する最良の方法は何でしょうか?(date_default_timezone_set('UTC');
が使用されると思いますか?)
タイプDATETIME
のフィールドに日時値を保持するのは自然な方法だと思います。
私自身の現在のPHPアプリケーションでの経験から、この情報に関するread
/write
操作のみが問題になる可能性があります。
プロセス全体を適切に実行するための可能な解決策の1つ(DATETIME
データ型を使用すると仮定)は、次のアプローチである可能性があります。
DATETIME
フィールドを取得してクエリ内'2011-10-02T23:25:42Z'
MySQL関数とDATE_FORMAT
フォーマット文字列を使用して'%Y-%m-%dT%H:%i:%sZ'
の形式の文字列表現に変換します(DATE_FORMATのドキュメント)DateTime
クラスオブジェクトやDateTime::createFromFormat
など)に有効な実際の日時表現に変換します。 'Y-m-d\TH:i:s\Z'
フォーマット文字列が指定された静的メソッド(T
およびZ
は、フォーマットディレクティブとして扱われないようにエスケープされます)(メソッドのドキュメント)。DateTime
クラスオブジェクトを以前と同じDateTime
クラスオブジェクトのformat
メソッドを使用してUTC形式の文字列表現でISO8601に変換します'Y-m-d\TH:i:s\Z'
フォーマット文字列(documentation =)。STR_TO_DATE
('%Y-%m-%dT%H:%i:%sZ'
フォーマット文字列を使用)のパラメーターとして準備された文字列を使用して、データベース情報に対してINSERT
/UPDATE
操作を実行します。これにより、実際のデータベースDATETIME
値(STR_TO_DATEのドキュメント =)。以下に、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データベースの間の日時値を操作するのに大いに役立ちました。
それがあなたにも役立つことを願っています。
日付と時刻を格納するためにDateTime
データ型を使用できます。
CAST
関数を使用して、そのような文字列をmysql DateTime
型にキャストします。
次に例を示します。
CAST("2011-10-02T23:25:42Z" AS DATETIME)
これにより、2011-10-02 23:25:42
が得られます。
これがお役に立てば幸いです。
strtotime
のphp
関数を使用して、日付を簡単に変換できます。
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
に日付を挿入するだけです。ここでは、両方のタイプについて知っておくべき最も重要なことを説明します。
タイムスタンプ
on update current_timestamp
を許可します。NULL
は可能なデフォルト値ではありませんUTC
に変換され、取得のためにUTC
から現在のタイムゾーンに変換されます。日時
5.6.5
の時点でのみ列の更新を許可する比較(たとえば、2つの日付/時刻間のレコードの取得)とクエリからの結果の順序付けに最適なのはどれですか?データベースが非常に大きい場合はどうでしょうか。
前に述べたように、ストレージが小さいため、非常に大きなデータベースにはtimestamp
を使用する必要があります。インデックスが高速であるため、比較のパフォーマンスが向上します。ただし、必ず日付が前述のtimestamp
の制限に適合することを確認してください。そうでない場合は、選択の余地がなく、datetime
を使用する必要があります。 。
strtotime
のドキュメント: http://php.net/manual/en/function.strtotime.php
そして、mysql*
[〜#〜]非推奨[〜#〜]関数を使用しないように毎日繰り返し続けるSOの回答者のために、使用してください挿入を行う場合は、PDO
またはmysqli*
。
日付を生の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');
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
日時を使用する方がよい理由は次のとおりです。