一個老掉牙問題 - 如何在 Batch 檔取得系統日期時間?

相關討論文很多,像保哥的這篇如何在 Batch 檔取得系統的日期、時間欄位 (第三版) 就介紹得有詳細,基本原理差不多是用 %date:~0,4% 從日期字串的第 0 個字元起取 4 個字元得到年... 等等。

不過,我在實測時遇上一個問題,%date% 傳回的日期格式會因 Windows 國別設定而訂,在某台日期格式被設成美國格式 M/d/yyyy 的 Windows Server 上,寫 %date:~0,4% 抓年份會抓到 "09/1" 這種鬼東西:

要解決這個問題不難,只需部署前先確定所在環境日期格式,要不調到符合要求,要不依目標環境量身訂製修改程式取值位置。 但我偏自找麻煩,希望程式本身多點「螂性」,在各種惡劣環境下都能生存,無腦地丟到 Windows 跑都不會壞掉,向打不死的小強看齊。

爬文找到好些做法,挑選幾個:(以取得 yyyyMMdd 為例)

  1. 使用 WMI 查詢 參考
    Windows Management Instrumentation Command, WMIC 是 WMI 的命令列工具,可從 DOS 執行 WMI 查詢, WMIC OS Get LocalDateTime 會傳回如下內容
    LocalDateTime
    20190919000000.000000+480
    
    FOR /F 可取出 20190919000000.000000+480,後面就簡單了。
    for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
    set yyyyMM=%X:~0,8%
    
    如果想分別取得年月日時分秒各數字,則有一招更快。WMIC Path Win32_LocalTime Get /Format:value 會回傳
    Day=19
    DayOfWeek=4
    Hour=17
    Milliseconds=
    Minute=24
    Month=9
    Quarter=3
    Second=48
    WeekInMonth=3
    Year=2019
    
    寫法 '''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% 等參數(但沒有補零)。 參考
  2. 使用 PowerShell:for /f "delims=" %%# in ('powershell get-date -format "{yyyyMMddHHmmss}"') do @set _date=%%#
    最大的優點是支援以 .NET 格式語法直接取回所需日期時間格式,省掉用 %X:~p,n% 拆解組裝的工夫,但需確定 Windows 環境允許使用 PowerShell。(有些管控較嚴的單位會禁止在正式環境執行 PowerShell)
  3. 使用 VBScri (此時忽然一陣噁心,這點就不繼續寫完了,請見諒)
  4. 借用 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

Post a comment