NOW() 返回資料庫伺服器當前的日期與時間(YYYY-MM-DD HH:MM:SS),是時間戳記錄、審計日誌、排程判斷、相對時間查詢的基石。但各資料庫函數名、時區行為、精度、效能特性差異顯著,本文系統梳理主流資料庫的 NOW/對應函數,並給出時區最佳實踐與效能建議。
| 資料庫 | 函數 | 返回類型 | 精度 | 時區行為 |
|---|---|---|---|---|
| MySQL / MariaDB | NOW() / SYSDATE() | DATETIME | 秒 (微秒可用 NOW(6)) | 會話時區 (time_zone 系統變數) |
| PostgreSQL | NOW() / CURRENT_TIMESTAMP / CLOCK_TIMESTAMP() | TIMESTAMP WITH TIME ZONE | 微秒 | 會話時區 (TimeZone 參數) |
| SQL Server | GETDATE() / SYSDATETIME() / SYSUTCDATETIME() | DATETIME / DATETIME2 / DATETIME2 | 3.33ms / 100ns / 100ns | 伺服器作業系統時區 (無會話時區概念) |
| Oracle | SYSDATE / SYSTIMESTAMP / CURRENT_TIMESTAMP | DATE / TIMESTAMP WITH TIME ZONE / TIMESTAMP WITH TIME ZONE | 秒 / 微秒 / 微秒 | 伺服器作業系統時區 / 會話時區 |
| SQLite | CURRENT_TIMESTAMP / datetime('now') | TEXT (ISO8601) | 秒 | UTC (預設) |
NOW():語句執行開始時刻固定,同一語句多次呼叫返回相同值。受 SET time_zone 影響。SYSDATE():實時 獲取,同一語句多次呼叫可能不同。不受 SET time_zone 影響,始終返回系統時區時間。複製/備份場景慎用(非確定性函數)。NOW() / CURRENT_TIMESTAMP:事務開始時刻固定,同一事務多次呼叫相同。CLOCK_TIMESTAMP():實時時鐘,每次呼叫不同。STATEMENT_TIMESTAMP():當前語句開始時刻。GETDATE():DATETIME,精度 ~3.33ms,舊版相容。SYSDATETIME():DATETIME2(7),精度 100ns,推薦新專案。SYSUTCDATETIME():UTC 時間,避免時區轉換 Bug,跨地域系統首選。SYSDATE:DATE 類型,精度秒,無時區資訊。SYSTIMESTAMP:TIMESTAMP WITH TIME ZONE,精度微秒,含資料庫時區位移。CURRENT_TIMESTAMP:會話時區 (ALTER SESSION SET TIME_ZONE)。+----+--------------+---------------------------+-------+---------+ | id | name | url | alexa | country | +----+--------------+---------------------------+-------+---------+ | 1 | Google | https://www.google.cm/ | 1 | USA | | 2 | 淘寶 | https://www.taobao.com/ | 13 | CN | | 3 | 菜鳥教程 | https://www.runoob.com/ | 4689 | CN | | 4 | 微博 | https://weibo.com/ | 20 | CN | | 5 | Facebook | https://www.facebook.com/ | 3 | USA | | 7 | stackoverflow| https://stackoverflow.com/ | 0 | IND | +----+--------------+---------------------------+-------+---------+
SELECT name, url, NOW() AS current_datetime FROM Websites;

SET GLOBAL time_zone = '+00:00'; 或 my.cnf: default-time-zone='+00:00'postgresql.conf: timezone = 'UTC'AT TIME ZONE 'UTC'ALTER DATABASE SET TIME_ZONE = '+00:00'; (需重啟)timezone=UTC / options=-c TimeZone=UTCconnectionTimeZone=SERVER + 伺服器 UTCIntl.DateTimeFormat、後端 DateTimeZone 轉換。NOW() 為非確定性函數:查詢緩存不緩存、複製時需行級格式、不可用於分區裁剪。NOW() 開銷。WHERE created_at >= NOW() - INTERVAL 1 DAY 可用索引,但 NOW() 每次執行值不同,緩存失效。-- MySQL WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) WHERE created_at BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW() -- PostgreSQL WHERE created_at >= NOW() - INTERVAL '7 days' -- SQL Server WHERE created_at >= DATEADD(DAY, -7, GETDATE()) -- Oracle WHERE created_at >= SYSDATE - 7
NOW() 看似簡單,實則牽涉時區、精度、複製、效能、確定性等深層機制。掌握各資料庫差異、統一 UTC 基線、應用層掌控時區轉換、避開非確定性陷阱,才能讓時間相關業務精準、可靠、可遷移。