SQLite 支援以下七個純量日期和時間函數
前六個日期和時間函數接受一個可選的時間值作為參數,後跟零個或多個修飾詞。strftime() 函數也將格式字串作為其第一個參數。timediff() 函數正好接受兩個參數,它們都是時間值。
SQLite 沒有專用的日期/時間資料類型。日期和時間值可以儲存為以下任何一種格式:
ISO-8601 符合 ISO 8601 日期/時間值的文字字串。範例:'2025-05-29 14:16:00' 儒略日數 自 -4713-11-24 12:00:00 以來的天數,包含小數天數。範例:2460825.09444444 Unix 時間戳記 自 1970-01-01 00:00:00 以來的秒數,包含小數秒數。範例:1748528160
這三種格式統稱為時間值。所有日期時間函數都接受 ISO-8601 文字或儒略日數作為時間值。通過添加可選的修飾詞參數 'auto' 或 'unixepoch',它們也可以接受 Unix 時間戳記。由於 timediff() 函數不接受修飾詞,因此它只能使用 ISO-8601 和儒略日數時間值。
date() 函數以 YYYY-MM-DD 格式返回日期文字。
time() 函數以 HH:MM:SS 格式返回時間文字,如果使用subsec 修飾詞,則格式為 HH:MM:SS.SSS。
datetime() 函數以 YYYY-MM-DD HH:MM:SS 格式返回日期和時間,如果使用subsec 修飾詞,則格式為 YYYY-MM-DD HH:MM:SS.SSS。
julianday() 函數返回儒略日 - 自公元前 4714 年 11 月 24 日格林威治時間中午以來的天數(包含小數天數)(公曆)。
unixepoch() 函數返回 Unix 時間戳記 - 自 1970-01-01 00:00:00 UTC 以來的秒數。unixepoch() 函數通常返回整數秒數,但使用可選的subsec 修飾詞時,它將返回小數秒數。
strftime() 函數根據指定為第一個參數的格式字串返回格式化的日期。格式字串支援標準 C 函式庫中strftime() 函數中最常見的替代,以及兩個新的替代:%f 和 %J。以下是截至 3.46.0 版 (2024-05-23) 的有效 strftime() 替代的完整列表。早期版本的 SQLite 可能不支援所有替代。如果看到未定義或不支援的替代,則結果為 NULL。
%d 月份中的日期:01-31 %e 月份中的日期(不含前導零):1-31 %f 小數秒數:SS.SSS %F ISO 8601 日期格式:YYYY-MM-DD %G 對應 %V 的 ISO 8601 年份 %g 對應 %V 的 ISO 8601 年份(兩位數) %H 小時:00-24 %I 12 小時制的小時:01-12 %j 一年中的第幾天:001-366 %J 儒略日數(含小數) %k 小時(不含前導零):0-24 %l %I(不含前導零):1-12 %m 月份:01-12 %M 分鐘:00-59 %p 根據小時顯示「AM」或「PM」 %P 根據小時顯示「am」或「pm」 %R ISO 8601 時間格式:HH:MM %s 自 1970-01-01 以來的秒數 %S 秒數:00-59 %T ISO 8601 時間格式:HH:MM:SS %U 一年中的第幾週 (00-53) - 第 01 週從第一個星期日開始 %u 星期幾 1-7,星期一為 1 %V ISO 8601 標準的星期數 %w 星期幾 0-6,星期日為 0 %W 一年中的第幾週 (00-53) - 第 01 週從第一個星期一開始 %Y 年份:0000-9999 %% %
其他日期和時間函數可以用 strftime() 表示
函數 等效的 strftime() date(...) strftime('%F', ...) time(...) strftime('%T', ...) datetime(...) strftime('%F %T', ...) julianday(...) CAST(strftime('%J', ...) as REAL) unixepoch(...) CAST(strftime('%s', ...) as INT)
date()、time() 和 datetime() 函數都返回文字,因此它們的 strftime() 等效函數是完全相同的。 然而,julianday() 和 unixepoch() 函數返回數值。它們的 strftime() 等效函數返回一個字串,該字串是對應數字的文字表示形式。
提供 strftime() 以外函數的主要原因是為了方便和效率。 julianday() 和 unixepoch() 函數分別返回實數值和整數值,並且不會產生使用 '%J' 或 '%s' 格式說明符與 strftime() 函數所導致的格式轉換成本或不準確性。
timediff(A,B) 函數返回一個字串,描述為了達到時間 A 需要添加到 B 的時間量。timediff() 結果的格式設計為易於閱讀。格式為
(+|-)YYYY-MM-DD HH:MM:SS.SSS
此時間差字串也是其他日期/時間函數的允許修飾符。以下不變量適用於時間值 A 和 B
datetime(A) = datetime(B, timediff(A,B))
月份和年份的長度有所不同。二月比三月短。閏年比非閏年長。timediff() 的輸出會將所有這些都考慮在內。timediff() 函數旨在提供時間跨度的易於理解的描述。如果您想知道兩個日期 A 和 B 之間的天數或秒數,則可以隨時執行以下操作之一
SELECT julianday(B) - julianday(A);
SELECT unixepoch(B) - unixepoch(A);
即使對於跨越不同天數的值 A 和 B,timediff(A,B) 也可能返回相同的結果 - 取決於起始日期。 例如,以下兩個 timediff() 呼叫都返回相同的結果(“-0000-01-00 00:00:00.000”),即使第一個時間跨度為 28 天,第二個時間跨度為 31 天
SELECT timediff('2023-02-15','2023-03-15');
SELECT timediff('2023-03-15','2023-04-15');
總結:如果您想要易於理解的時間跨度,請使用 timediff()。 如果您想要精確的時間差(以天或秒為單位),請使用兩個 julianday() 或 unixepoch() 呼叫之間的差值。
時間值可以採用以下任何格式。 該值通常是一個字串,但在格式 12 的情況下,它可以是一個整數或浮點數。
格式 5 到 7 中,「T」是一個用於分隔日期和時間的字元,如同 ISO-8601 標準的要求。格式 8 到 10 僅指定時間,預設日期為 2000-01-01。格式 11,字串「now」,會被轉換為目前的日期和時間,其值取自使用中 sqlite3_vfs 物件的 xCurrentTime 方法。「now」作為日期和時間函式的參數,在同一個 sqlite3_step() 呼叫中的多次使用,總是會返回完全相同的值。日期和時間使用 協調世界時 (UTC)。格式 12 是以整數或浮點數表示的 儒略日。如果格式 12 後面緊跟著 「auto」 或 「unixepoch」 修飾符,則它也可能被解釋為 Unix 時間戳記。
格式 2 到 10 之後可以選擇性地加上時區指示符,格式為「[+-]HH:MM」或僅為「Z」。日期和時間函式內部使用 UTC 或「Zulu」時間,因此「Z」後綴表示不進行時區調整。任何非零的「HH:MM」後綴會從指示的日期和時間中減去,以便計算 Zulu 時間。例如,以下所有時間值都是等效的:
2013-10-07 08:23:19.120
2013-10-07T08:23:19.120Z
2013-10-07 04:23:19.120-04:00
2456572.84952685
在格式 4、7 和 10 中,小數秒值 SS.SSS 在小數點後可以有一位或多位數字。範例中正好顯示三位數字,因為只有前三位數字對結果有效,但輸入字串可以少於或多於三位數字,日期/時間函式仍然可以正常運作。同樣地,格式 12 顯示了 10 位有效數字,但日期/時間函式實際上會接受表示儒略日所需的任意位數。
除了 timediff() 函式之外,所有函式中的時間值(以及所有修飾符)都可以省略,在這種情況下,會假設時間值為「now」。
除了 timediff() 之外,所有日期/時間函式的時間值參數後面都可以跟著零個或多個修飾符,這些修飾符會更改日期和/或時間。每個修飾符都是應用於其左側時間值的轉換。修飾符從左到右應用;順序很重要。可用的修飾符如下:
前十三個修飾符(1 到 13)將指定的時間量添加到其左側參數指定的日期和時間。修飾符 1 到 6 名稱結尾的「s」字元是可選的。NNN 值可以是任何浮點數,可以選擇性地加上「+」或「-」前綴。
**時間偏移修飾符**(7 到 13) 將時間值移動指定的年、月、日、小時、分鐘和/或秒數。格式 10 到 13 需要起始的「+」或「-」,但格式 7、8 和 9 則為可選。更改從左到右應用。首先將年份偏移 YYYY,然後將月份偏移 MM,然後將日期偏移 DD,依此類推。timediff(A,B) 函式以格式 13 返回時間偏移,將時間值 B 偏移到 A。
由於一個月或一年的長度會隨著月份或年份而變化,因此在日期加上月份和/或年份時,可能會產生歧義。例如,2024-02-29 後一年是哪一天?是 2025-02-28 還是 2025-03-01?或者 2023-12-31 後兩個月是哪一天?是 2024-02-29 還是 2024-03-02?對於如何解決這種歧義沒有共識,因此可以使用「無條件進位」(ceiling,修飾詞 14)和「無條件捨去」(floor,修飾詞 15)修飾詞,讓程式設計師自行決定。如果時間位移後的下一個修飾詞是「無條件進位」,則日期中的任何歧義都會解析為較晚的日期。「無條件捨去」修飾詞則會將歧義解析為前一個月的最後一天。預設行為是「無條件進位」。
「起始」(start of,修飾詞 16 到 18)修飾詞會將日期回溯到目標月份、年份或日期的起始。
「星期幾」(weekday)修飾詞會將日期往前推移(如果需要)到下一個星期幾編號為 N 的日期。星期日為 0,星期一為 1,依此類推。如果日期已經是所需的星期幾,則「星期幾」修飾詞不會更改日期。
「unixepoch」修飾詞(20)僅在緊接在 DDDDDDDDDD 格式的時間值之後才有效。此修飾詞會使 DDDDDDDDDD 不像通常那樣被解釋為儒略日數,而是被解釋為Unix 時間——自 1970 年以來的秒數。如果「unixepoch」修飾詞後面沒有接表示自 1970 年以來秒數的 DDDDDDDDDD 格式的時間值,或者如果有其他修飾詞將「unixepoch」修飾詞與前面的 DDDDDDDDDD 分隔開來,則其行為未定義。
「儒略日」(julianday)修飾詞必須緊接在初始時間值之後,且該時間值必須是 DDDDDDDDD 格式。任何其他使用「儒略日」修飾詞的方式都是錯誤的,並且會導致函式返回 NULL。「儒略日」修飾詞會強制將時間值數字解釋為儒略日數。由於這是預設行為,「儒略日」修飾詞幾乎等同於無作用。唯一的區別是,加上「儒略日」會強制使用 DDDDDDDDD 時間值格式,如果使用任何其他時間值格式,則會導致返回 NULL。
「自動」(auto)修飾詞必須緊接在初始時間值之後。如果時間值是數值(DDDDDDDDD 格式),則「自動」修飾詞會根據其大小將時間值解釋為儒略日數或 Unix 時間戳記。如果值介於 0.0 和 5373484.499999 之間,則會將其解釋為儒略日數(對應於 -4713-11-24 12:00:00 到 9999-12-31 23:59:59 之間的日期,含)。對於超出有效儒略日數範圍,但介於 -210866760000 到 253402300799 之間的數值,「自動」修飾詞會將該值解釋為 Unix 時間戳記。其他數值超出範圍,並會導致返回 NULL。對於 ISO 8601 文字時間值,「自動」修飾詞無作用。「自動」修飾詞的設計目的是即使在不知道資料庫檔案中儲存的時間值格式,或者在同一欄位在不同列上儲存不同格式時間值的情況下,也能處理時間值。 「自動」修飾詞會自動選擇適當的格式。然而,存在一些歧義。1970 年前 63 天的 Unix 時間戳記將被解釋為儒略日數。當資料集保證不包含該範圍內的日期時,「自動」修飾詞非常有用,但對於可能使用 1970 年最初幾個月的日期的應用程式,則應避免使用。
「localtime」修飾詞假設其左側的時間值是世界協調時間 (UTC),並調整該時間值使其成為當地時間。如果「localtime」後面的時間不是 UTC,則行為未定義。「utc」修飾詞與「localtime」相反。「utc」假設其左側的時間值是當地時區,並將該時間值調整為 UTC。如果左側的時間不是當地時間,則「utc」的結果未定義。
「subsecond」修飾詞(可縮寫為「subsec」)會提高 datetime()、time() 和 unixepoch() 的輸出解析度,以及 strftime() 中「%s」格式字串的解析度。「subsecond」修飾詞對其他日期/時間函數沒有影響。目前的實作將解析度從秒提高到毫秒,但在未來版本的 SQLite 中可能會提高到更高的解析度。當「subsec」與 datetime() 或 time() 一起使用時,結尾的秒數欄位後面會接著一個小數點和一個或多個數字,以顯示小數秒。當「subsec」與 unixepoch() 一起使用時,結果是一個浮點值,表示自 1970-01-01 以來的秒數和小數秒數。「subsecond」和「subsec」修飾詞具有特殊屬性,它們可以作為日期/時間函數的第一個參數(或作為 strftime() 格式字串後的第一個參數)。發生這種情況時,通常在第一個參數中的時間值會被理解為「現在」。例如,要以毫秒精度取得目前時間(以自 1970 年以來的秒數表示)的捷徑是:
SELECT unixepoch('subsec');
計算目前的日期。
SELECT date();
計算目前月份的最後一天。
SELECT date('now','start of month','+1 month','-1 day');
計算給定 Unix 時間戳記 1092941466 的日期和時間。
SELECT datetime(1092941466, 'unixepoch');
SELECT datetime(1092941466, 'auto'); -- 對於 1970 年早期不適用!
計算給定 Unix 時間戳記 1092941466 的日期和時間,並根據您的當地時區進行調整。
SELECT datetime(1092941466, 'unixepoch', 'localtime');
計算目前的 Unix 時間戳記。
SELECT unixepoch();
SELECT strftime('%s');
計算自美國《獨立宣言》簽署以來的天數。
SELECT julianday('now') - julianday('1776-07-04');
計算自 2004 年特定時刻以來的秒數
SELECT unixepoch() - unixepoch('2004-01-01 02:34:56');
計算今年十月第一個星期二的日期。
SELECT date('now','start of year','+9 months','weekday 2');
計算自 Unix 紀元以來的時間(以秒為單位,精確到毫秒)
SELECT (julianday('now') - 2440587.5)*86400.0;
SELECT unixepoch('now','subsec');
計算如果亞伯拉罕·林肯還活著,他今天的年齡
SELECT timediff('now','1809-02-12');
當地時間的計算很大程度上取決於政治家的想法,因此很難針對所有地區都正確計算。在此實作中,標準 C 函式庫函數 localtime_r() 用於協助計算當地時間。localtime_r() C 函數通常僅適用於 1970 年到 2037 年之間的年份。對於此範圍之外的日期,SQLite 會嘗試將年份映射到此範圍內的等效年份,進行計算,然後將年份映射回原來的年份。
這些函數僅適用於 0000-01-01 00:00:00 到 9999-12-31 23:59:59 之間的日期(儒略日數 1721059.5 到 5373484.5)。對於超出此範圍的日期,這些函數的結果未定義。
非 Vista 版本的 Windows 平台僅支援一套日光節約時間 (DST) 規則。Vista 僅支援兩套。因此,在這些平台上,歷史 DST 的計算將會不正確。例如,在美國,2007 年 DST 規則有所變更。非 Vista 版本的 Windows 平台會將新的 2007 年 DST 規則套用至所有之前的年份。Vista 的處理方式較佳,能正確計算回溯至 1986 年(當時規則也有變更)的結果。
所有內部計算均採用格里曆 (公曆)系統。它們也假設每天的長度正好是 86400 秒;不包含閏秒。
本頁面最後修改時間:2024 年 8 月 14 日 17:04:32 UTC