如何在 Batch 檔跨國別語系取得系統日期時間?
5 |
一個老掉牙問題 - 如何在 Batch 檔取得系統日期時間?
相關討論文很多,像保哥的這篇如何在 Batch 檔取得系統的日期、時間欄位 (第三版) 就介紹得有詳細,基本原理差不多是用 %date:~0,4% 從日期字串的第 0 個字元起取 4 個字元得到年... 等等。
不過,我在實測時遇上一個問題,%date% 傳回的日期格式會因 Windows 國別設定而訂,在某台日期格式被設成美國格式 M/d/yyyy 的 Windows Server 上,寫 %date:~0,4% 抓年份會抓到 "09/1" 這種鬼東西:
要解決這個問題不難,只需部署前先確定所在環境日期格式,要不調到符合要求,要不依目標環境量身訂製修改程式取值位置。 但我偏自找麻煩,希望程式本身多點「螂性」,在各種惡劣環境下都能生存,無腦地丟到 Windows 跑都不會壞掉,向打不死的小強看齊。
爬文找到好些做法,挑選幾個:(以取得 yyyyMMdd 為例)
- 使用 WMI 查詢 參考
Windows Management Instrumentation Command, WMIC 是 WMI 的命令列工具,可從 DOS 執行 WMI 查詢, WMIC OS Get LocalDateTime 會傳回如下內容
用 FOR /F 可取出 20190919000000.000000+480,後面就簡單了。LocalDateTime 20190919000000.000000+480
如果想分別取得年月日時分秒各數字,則有一招更快。WMIC Path Win32_LocalTime Get /Format:value 會回傳for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x set yyyyMM=%X:~0,8%
寫法 '''for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do @for /f %%@ in ("%%#") do @set %%@''' 巧妙地以迴圈依序執行 set Day=19, set DayOfWeek=4... ,直接轉換出 %Year%、%Month%、%Day% 等參數(但沒有補零)。 參考Day=19 DayOfWeek=4 Hour=17 Milliseconds= Minute=24 Month=9 Quarter=3 Second=48 WeekInMonth=3 Year=2019
- 使用 PowerShell:
for /f "delims=" %%# in ('powershell get-date -format "{yyyyMMddHHmmss}"') do @set _date=%%#
最大的優點是支援以 .NET 格式語法直接取回所需日期時間格式,省掉用 %X:~p,n% 拆解組裝的工夫,但需確定 Windows 環境允許使用 PowerShell。(有些管控較嚴的單位會禁止在正式環境執行 PowerShell) - 使用 VBScri (此時忽然一陣噁心,這點就不繼續寫完了,請見諒)
- 借用 UnxUtils 的 date.exe,date.exe +"%Y-%m-%d" 可指定日期格式,不受系統設定影響, 缺點是需要額外部署程式。參考
除了上述做法,還有一些奇技淫巧型的解法,但不如前述幾種做法直覺簡潔,不推: 參考
- 用 MAKECAB 產生報表檔,報表檔中有日期
- 從 ROBOCOPY 的輸出訊息取得日期時間
- 用 TYPEPERF 讀取時鐘計數器
花了點時間搞懂這個沒太多營養的小問題,但學到好用的 WMIC 及一些批次檔語法,也算有收獲。
Comments
# by Anonymous
https://ss64.com/nt/syntax-getdate.html
# by Jeffrey
to Anonymous, 感謝補充。
# by Frankie
>> 使用 VBScri (此時忽然一陣噁心,這點就不繼續寫完了,請見諒) 看到這句忍不住笑了出來. 謝謝你的分享 :-)
# by 路人甲
https://gist.github.com/cjwinchester/64a921d1190aefb8eae1
# by Thor
Windows 11 24H2 預設不安裝 wmic https://learn.microsoft.com/zh-tw/windows/whats-new/deprecated-features