如何将 UTC ISO8601 日期存储在 MySQL 数据库中?

2022-08-30 13:26:06

我有数千个以下格式的日期:

2011-10-02T23:25:42Z(在 UTC 中也称为 ISO 8601)

我应该使用什么MySQL数据类型在MySQL数据库中存储这样的ISO8601日期?例如,还是其他什么?Datetimetimestamp

哪个最适合比较(例如,获取两个日期/时间之间的记录)并对查询结果进行排序?如果数据库非常大怎么办?

将上述PHP字符串转换为MySQL存储的最佳方法是什么?(我猜会用吗?date_default_timezone_set('UTC');


答案 1

我认为将日期时间值保留在类型字段中将是一种自然的方式。DATETIME

根据我自己对当前PHP应用程序的经验,仅/与此信息有关的操作可能会有问题。readwrite

正确执行整个过程的可能解决方案之一(假设您使用数据类型)可能是以下方法:DATETIME

读取 PHP 使用的 DATETIME 值

  1. 从数据库中获取字段,通过使用MySQL函数和格式化字符串的形式,以查询中的字段转换为字符串表示形式(DATE_FORMATDATETIME'2011-10-02T23:25:42Z'DATE_FORMAT'%Y-%m-%dT%H:%i:%sZ')
  2. 以这种特定格式读取提取的列值,并在PHP中将其从字符串转换为对PHP有效的真实日期时间表示(例如类对象和给定格式化字符串的静态方法(并且被转义以避免将它们视为格式化指令)(该方法的文档)。DateTimeDateTime::createFromFormat'Y-m-d\TH:i:s\Z'TZ
  3. 使用转换后的值作为所有适用逻辑的真实日期时间值,例如实际日期比较(不是文本比较)等。

将 PHP 日期时间写入 MySQL 数据库

  1. 即.PHP,使用类对象的方法将类对象转换为我们的ISO 8601 UTC格式的字符串表示,其格式与格式化字符串(文档)之前相同。DateTimeDateTimeformat'Y-m-d\TH:i:s\Z'
  2. 使用这种准备好的字符串作为MySQL函数(带格式化字符串)的参数对数据库信息执行/操作,将其转换为实际数据库值(STR_TO_DATE上的文档)。INSERTUPDATESTR_TO_DATE'%Y-%m-%dT%H:%i:%sZ'DATETIME

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数据库之间操作日期时间值方面帮助了我很多。

我希望它也可能对你有所帮助。


答案 2

可以使用数据类型来存储日期和时间。DateTime

使用函数将此类字符串转换为 mysql 类型。CASTDateTime

下面是一个示例:

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

这将给你.2011-10-02 23:25:42

希望这会帮助你。


推荐