只要幾秒鐘,就能透過瀏覽器端的隨機日期產生器在 SQL Server 中產生隨機日期,該工具會以均勻方式從一個含頭含尾的 YYYY-MM-DD 範圍中取樣,嚴格驗證每一個日曆值,並在你的機器上以穩定的 ISO 格式輸出最多 1,000 筆結果。這種做法取代了大家熟悉的 T-SQL 模式,也就是 RAND() 搭配 DATEADD 與 CHECKSUM,後者雖然撰寫快速,但難以稽核,而且在接近日光節約時間邊界時容易產生飄移。由於改用整數型 UTC 日序數,而不是在當地午夜加上小時數,產生器得以避免在 SQL Server 指令碼中常見的差一日期錯誤。每個被接受的序數都是透過拒絕取樣法從 Web Crypto 的 32 位元無號字對應而來,因此範圍內的每個日曆日都有完全相同的選取機率,不會有任何模數偏差悄悄混入。嚴格的驗證機制會直接拒絕像 2025-04-31 或 1900-02-29 這類不可能的輸入,而不是悄悄把它們往後遞延,這讓測試固定資料保持真實。整個流程都在用戶端執行,所以起始日期、結束日期以及產生的清單都不會離開產生它們的那台裝置。

SQL Server 常見的隨機日期模式
SQL Server 開發人員在需要隨機日期時,通常最常使用 RAND() 內建函式。經典的模式是將 RAND() 包進 DATEADD,並以 CHECKSUM(NEWID()) 作為種子,讓 SELECT 中的每一列都得到不同的值。類似 SELECT DATEADD(DAY, ABS(CHECKSUM(NEWID())) % @Days, @StartDate) 的查詢,並聯結到數字表後,就能在要求的時間區間內產生一組分散的日期。這種技術有完整的文件記載,並且能在預存程序內運作,當測試資料必須隨部署一起重新產生時,相當方便。
那種做法有三個值得指出的弱點。首先,當範圍大小不是 2 的次方時,模數運算會產生偏差,某些日期出現的頻率會略高於其他日期,特別是在範圍較短的情況下。其次,在 SQL Server 中對 DATETIME 加上天數,會受到工作階段的 datefirst、語言與時區設定影響;同一份指令碼跨伺服器複寫時,可能產生略有不同的結果表。第三,該公式只能在 SQL Server 工作階段中運作,因此任何人若想要一份用於文件、簡報或人工 QA 流程的一次性日期清單,都得特地打開 SSMS 或 Azure Data Studio,只為了複製少數幾個值。
瀏覽器工具與 T-SQL 指令碼的不同之處
隨機日期產生器是一個輕量的用戶端頁面,專為開發人員在不想開啟資料庫連線的情況下,需要一份乾淨的日期清單而設計。你輸入起始日期與結束日期,選擇要抽取多少個值,再決定是否允許重複。產生的清單會以純文字的 YYYY-MM-DD 字串呈現,可以直接貼進 INSERT 陳述式、CSV 固定資料或 Markdown 測試計畫中。
由於範圍兩端都是含頭含尾,像 2024-02-28 到 2024-03-01 這麼小的區間,可以回傳三個有效日曆日中的任何一天,包括閏日。清單是在瀏覽器內部使用 UTC 日序數產生,因此無論是東京的伺服器、柏林的開發人員,還是聖保羅的審閱者,只要輸入相同,就會得到相同的日期。沒有任何資料列會透過網路傳送,當日期清單代表機密的測試固定資料、或尚未獲准上傳的資料集時,這點相當重要。
偏差問題值得用一個算過的例子說明。N 天的範圍中,可接受的區間為 2^32 中的 floor(2^32 / N) × N 個可能的 32 位元無號字。當 N = 366(以閏年 2024 為例)時,floor(4,294,967,296 / 366) = 11,734,883,因此可接受區間涵蓋 11,734,883 × 366 = 4,294,967,178 個值,而被拒絕的尾部僅包含 4,294,967,296 - 4,294,967,178 = 118 個值。可接受區間中的每個序數,因此對應到相同數量的 32 位元抽取,這就是為何範圍內的每個日曆日最終都具有相同的機率。
| 面向 | SQL Server RAND() 模式 | 隨機日期產生器 |
|---|---|---|
| 執行環境 | 在 T-SQL 工作階段中執行 | 完全在瀏覽器中執行 |
| 抽樣偏差 | 在非 2 的次方範圍上有模數偏差 | 透過拒絕取樣消除模數偏差 |
| 範圍端點 | 必須小心撰寫才會含頭含尾,容易出錯 | 依合約兩端皆含頭含尾 |
| 無效日期 | 部分函式會悄悄往前遞延 | 嚴格驗證會拒絕並回報錯誤 |
| 輸出格式 | 結果集中的 DATETIME 資料列 | 可直接複製的純 YYYY-MM-DD 文字 |
| 可重現性 | 由 SQL Server 工作階段驅動 | 請儲存輸出,因為 Web Crypto 無法設定種子 |
如何使用此工具產生隨機日期
- 開啟隨機日期產生器,在 YYYY-MM-DD 欄位中輸入起始日期。任何從 0001-01-01 到 9999-12-31 的有效西曆日期都可接受,包括像 2024-02-29 這類閏日。
- 以相同格式輸入結束日期。結束日期必須等於或晚於起始日期;單日範圍是有效的,並且必定回傳那一天。
- 輸入介於 1 到 1,000 之間的數量。空白值、小數、零、負數,或任何超過 1,000 的值都會產生錯誤,說明允許的範圍,而且不會截斷任何內容。
- 選擇是否允許重複。開啟重複時,每一次要求的抽取都會獨立地從完整含頭含尾範圍中取樣,因此同一個日期可能會合法地出現多次。關閉重複時,產生器會執行稀疏的部分 Fisher-Yates 不放回選擇;若數量超過範圍內的天數,則會回報錯誤,而不是縮短清單或悄悄啟用重複。
- 點擊「產生」,然後檢查顯示的範圍與數量,確認與你的輸入一致。編輯任一端點、變更數量,或切換重複模式,都會清除舊的清單與先前的錯誤,確保先前設定下的任何結果都不會留在畫面上,假裝符合目前的控制項。
- 複製或記錄你需要的日期。這些值是穩定的 YYYY-MM-DD 字串,適用於 INSERT 陳述式、CSV 固定資料或手寫的測試計畫。
DST 飄移與 UTC 序數法
許多自行拼湊的隨機日期指令碼之所以出錯,是因為它們是在當地午夜加上小時數。在時鐘往前調撥的那天,加上 24 小時會落在隔天的 01:00 而不是午夜,因此產生的日期字串會跳過整個日曆日。而在秋季往後調撥時,相同的算式會落在 23:00,因此連續兩次抽取可能產生相同的顯示日期。只要主機遵循日光節約時間,SQL Server 也不例外。
隨機日期產生器透過將每個日曆日期視為相對於 1970-01-01 的整數日位置,來避免這個問題。嚴格的 YYYY-MM-DD 輸入會透過在 UTC Date 物件上設定年、月、日來解析,接著讀回這些元件以確認該值已被接受,然後將得到的 UTC 毫秒值除以精確的 86,400,000 以產生整數日序數。取樣在這些整數位置執行,並使用 UTC 的 getter 將選中的位置格式化回 YYYY-MM-DD,因此在每台裝置上顯示的日期永遠相同。ECMAScript 對 Date 物件的規範定義了此行為,也是驗證器所遵循的西曆閏年規則的來源:2000-02-29 與 2024-02-29 有效,而 1900-02-29 與 2023-02-29 則會被拒絕。
限制與驗證規則
此工具遵循的合約相當簡潔,足以用一張表整理出來。事先了解限制,是避免在大量貼上後遇上令人困惑錯誤的最簡單方法。
| 輸入 | 接受 | 拒絕或拒絕時的行為 |
|---|---|---|
| 起始與結束日期 | 從 0001-01-01 到 9999-12-31 的 YYYY-MM-DD | 超出範圍或格式錯誤的值會產生錯誤,而不是悄悄修正 |
| 日期順序 | 起始早於或等於結束 | 起始晚於結束會產生錯誤 |
| 數量 | 介於 1 到 1,000 的整數 | 空白、小數、零、負數或超過 1,000 都會產生錯誤,說明允許的範圍 |
| 關閉重複模式 | 數量不超過含頭含尾的天數 | 數量超過天數會產生錯誤;清單絕不會被縮短 |
| 不可能的日曆值 | 僅接受真實的西曆日期 | 2025-04-31、1900-02-29 與類似值會被拒絕 |
| 0001 到 0099 年 | 保留所寫的字面年份 | 不會被平移到二十世紀,這歸功於 setUTCFullYear |
| 隨機來源 | Web Crypto getRandomValues 的 Uint32 值 | 絕不會使用 Math.random;來源失敗會回報錯誤 |
適用與不適用的情境
這份清單適用於 SQL Server 測試固定資料、範例排程、隨機練習、寫作提示,或需要一組看起來合理且能貼進 INSERT 陳述式的日期分布的展示。這些值也適合用於充實文件、建立範例儀表板,或在實際後端尚未串接之前,先勾勒出 Excel 樣稿。若要做可重現的軟體測試,請複製輸出並與測試一同儲存;若需要每次執行都得到相同的日期,則請使用你自己可設定種子的產生器;Web Crypto 依設計在本介面中無法設定種子。
這份清單並非預測、預約服務、法律期限計算工具、營業日曆、假日曆、時區轉換器,也非時間戳記產生器。日期除了內部的 UTC 序數法之外,不包含任何時段或時區偏移,因此同一日期上的兩個不同時間戳記不在範圍內。清單不會排除週末、國定假日、歷史曆法轉換或組織特定的封鎖日期;在真實流程中仰賴某個日期之前,請另行檢查這些限制。對於涉及財務、法律、競賽、安全或稽核後果的抽籤,請採用具有獨立監督並保留證據的書面程序,而非單一瀏覽器工具。若你的工作同時涉及 SQL Server 與 PostgreSQL,對應的 PostgreSQL 版本遵循相同的含頭含尾範圍邏輯,值得與本文一同閱讀。
若想深入了解,請參閱在瀏覽器中執行的隨機 IP 產生器 API 替代方案。