用于日期算术和比较的可移植SQL

aaz*_*aaz 5 php sql datetime

SQL

用于存储用户会话的表:

CREATE TABLE sessions (
    user_id INT,
    expires TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

要创建会话:

INSERT INTO sessions (user_id, expires) VALUES (:user_id,
    CURRENT_TIMESTAMP + INTERVAL '+15 minutes');
Run Code Online (Sandbox Code Playgroud)

要检索会话:

SELECT * FROM sessions WHERE user_id = :user_id AND
    CURRENT_TIMESTAMP < expires;
Run Code Online (Sandbox Code Playgroud)

问题

  • 这是可移植的SQL吗?
    这适用于通过PHP PDO扩展(不包括SQLite)提供的任何数据库吗?

  • 这在不同的时区是否正确?跨夏令时调整?
    混合CURRENT_TIMESTAMP(包括时区信息)与TIMESTAMP列(没有)的任何问题?

Nic*_*rey 3

根据我的经验,日期/时间值在 SQL 方言中是相当有问题的。

\n\n
    \n
  • Oracle 支持DATETIMESTAMPTIMESTAMP WITH TIME ZONETIMESTAMP WITH LOCAL TIME ZONE。\n
      \n
    • DB2 支持日期、时间和时间戳。
    • \n
    • SQL Server 支持 DATETIME 和(最近)DATE。SQL Server 有一种TIMESTAMP数据类型,但它并不是您想象的那样。
    • \n
    • MySQL 支持 DATE、DATETIME、TIMESTAMP、TIME 和 YEAR
    • \n
    • PostgresSQL 支持 TIMESTAMP 和 TIME(带或不带时区)以及 DATE
    • \n
  • \n
\n\n

如果我必须以绝对可移植的方式处理日期/时间值,我会将值存储为 ISO8601 紧凑形式的 char/varchar

\n\n
YYYYMMDDTHHMMSS[\xc2\xb1HH:MM]\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中时间部分是 24 小时/军用时间。如果您需要时区支持,请包含与 UTC 的偏移量,或“Z”以指示祖鲁 (UTC) 时间。严格来说,如果没有“Z”后缀,ISO 8601 日期/时间值应该被解释为当地时间。

\n\n

根据您的需要,可能值得将日期和时间部分分成单独的列。

\n\n

ISO8601给您

\n\n
    \n
  • 可移植性
  • \n
  • 适当的整理/比较
  • \n
  • 易于解析
  • \n
\n