日時を環境変数に得る 概要 †環境変数に日時を得たいケースがある。
の3パターンについて、dateやtimeコマンドを使う方法、 環境変数DATEやTIMEを使う方法それぞれについて記す。 地域のオプションで日付を和暦にしたり、時刻を12時間制にした場合、 上記コマンドの結果や環境変数の値も影響を受ける*1。
日時機能については、機能差異/Win2KとWinXPも参照。 時刻をtime/tコマンドで得る †time/tコマンドで得られる結果の書式は HH:mm で秒は得られないが、 分までで十分な場合はこの方法が簡単である。 for /f "delims=: tokens=1,2" %%A in ('time/t') do set HH=%%A&set MM=%%B for /f "delims=: tokens=1,2" %%A in ('time/t') do set HHMM=%%A%%B 日付をdate/tコマンドで得る †date/tコマンドで得られる結果の書式は yyyy/mm/dd で、 Win2Kの場合は空白をはさんで曜日が後ろに付く。 for /f "tokens=1-3 delims=/- " %%A in ('date/t') do set Y=%%A&set M=%%B&set D=%%C for /f "tokens=1-3 delims=/- " %%A in ('date/t') do set YMD=%%A%%B%%C 空白もデリミタにする必要があるので、delims=/- と " の間に空白を置く。 時刻をTIME環境変数から得る †秒まで得たい場合は、time/tコマンドでは得られない。 set HHMMSS=%TIME:~0,2%%TIME:~3,2%%TIME:~6,2% というコードを目にすることがあるが、これには2点問題がある。
1.の理由だが、 :loop set X=%TIME%/%TIME% if %X:~0,11% == %X:~-11% goto loop を実行すると、しばらくしてループから抜ける。
つまり、同一の文でも複数回 %TIME% を記述するとその度に最新の時刻を参照する。 set T=%TIME: =0% set HHMMSS=%T:~0,2%%T:~3,2%%T:~6,2% のように、一旦別の環境変数にセットすることで1.の問題を回避し、 その時、空白 を 0 に置換することで2.の問題も処理できる。 日付をDATE環境変数から得る †Win2Kでは、yyyy/mm/dd の前に曜日が付くため、Win2KとWinXPの両方で動く スクリプトにしたければ、文字位置を後ろから数えて指定する。 前述の時刻と同様、レアケースだが日が変わるタイミングで実行すると 誤った日付となる可能性があるため、一旦別の環境変数にセットする必要がある。 ただし、定時刻起動の処理など明らかに0時直前に実行されることが無いケースでは %DATE%のまま使っても問題ない*2。 set D=%DATE% set YYYYMMDD=%D:~-10,4%%D:~-5,2%%D:~-2% デリミタが / であるという前提を置いて良ければ、 set D=%DATE:/=% set YYYYMMDD=%D:~-8% さらに、WinXPに限定してよければ、 set YYYYMMDD=%DATE:/=% でよい。 日時を得る †日時を同一コマンドや同一環境変数で得ることは出来ないので、
日付と時刻を別々のタイミングで取得する必要がある。 :retry set D=%DATE% set T=%TIME: =0% if not %D% == %DATE% goto retry set YYYYMMDDHHMMSS=%D:~-10,4%%D:~-5,2%%D:~-2%%T:~0,2%%T:~3,2%%T:~6,2% date/t や time/t コマンドを使うことも出来るがどうせ一旦別の環境変数に セットする必要があるので、環境変数を使うほうが簡単である。 別の方法として、VBSのNow()関数を使って日付・時刻を同時に得る方法がある。 echo WScript.Echo Now() > tmp.vbs for /f "tokens=1-6 delims=/-: " %%A in ('cscript //nologo tmp.vbs' ) do set YYYYMMDDHHMMSS=%%A%%B%%C%%D%%E%%F del tmp.vbs 年月日の書式が変更されれている状況で日付を得る (WinXP) †コントロールパネルでアメリカ式、ヨーロッパ式のように、
年月日の順を変更している場合、
また曜日表示を指定している場合にでも年月日を得る方法を考える。 WinXPの場合は、reg コマンドでレジストリの値が取得できるので、
コントロールパネルの地域と言語のオプションで設定した日付書式を参照できる。 for /f "skip=4 tokens=2*" %%A in ('reg query "HKCU\Control Panel\International" /v sShortDate') do set FMT=%%B 書式には空白が含まれる可能性があるので、tokens=2* として3番目以降をまとめて取得する。 set YYYY=&set YY=&set MM=&set M=&set DD=&set D=&set DDD= for /f "tokens=1-4 delims=/-() " %%A in ("%FMT%") do ( for /f "tokens=1-4 delims=/-() " %%a in ("%DATE%") do ( set %%A=%%a&set %%B=%%b&set %%C=%%c if not "%%D"=="" set %%D=%%d )) if not "%YY%"=="" set YYYY=20%YY% if not "%M%"=="" set MM=0%M% set MM=%MM:~-2% if not "%D%"=="" set DD=0%D% set DD=%DD:~-2% set YYYYMMDD=%YYYY%%MM%%DD% 年月日の書式が変更されれている状況で日付を得る (Win2000) †Win2000には reg コマンドは無いが、VBS+WSHを使えばレジストリ値を取得できる。 >tmp.vbs echo Set WShell=WScript.CreateObject("WScript.Shell") >>tmp.vbs echo WScript.Echo WShell.RegRead("HKCU\Control Panel\International\sShortDate") for /f "delims=" %%A in ('cscript //nologo tmp.vbs') do set FMT=%%A del tmp.vbs set FMT=ddd %FMT:ddd=% 以降は WinXP と同じ方法で年月日を取得できる。 |