読者です 読者をやめる 読者になる 読者になる

1.21 jigowatts

Great Scott!

Windowsバッチ処理で日付を取得するときロケールに影響されたくない

概要

バッチ処理で現在日付をファイル名に付与したい!
そんな時は以下のように切り取ることで好きなフォーマットに加工することができるので、ファイル名に使ったり、ログに出力したりすることができます。

>echo %date%
2015/01/26
>echo %date:~-10,4%%date:~-5,2%%date:~-2,2%
20150126
>echo %time:~-11,2%%time:~-8,2%%time:~-5,2%
161339

ですが、ローカル環境でテストしていざサーバで実行するとむちゃくちゃになることがあります。

>echo %date%
Mon 01/26/2015
>echo %date:~-10,4%%date:~-5,2%%date:~-2,2%
01/2/215

これはシステムロケールが異なる場合に発生します。
今回はC#のコンソールアプリからロケールをja_JPに指定して日付を取得してみました。

実装

C#のコンソールアプリを作ります。
引数に"d"が渡された場合は日付を、引数に"t"が渡された場合は時間をコンソールに表示します。エラー時はERRORLEVELに200を返します。
GetDate.exe

class Program
{
    static int Main(string[] args)
    {
        if (args.Count() != 1) 
        {
            return 200;
        }
        switch (args[0]) 
        {
            case "d":
                GetDate();
                return 0;
            case "t":
                GetTime();
                return 0;
            default:
                return 200;
        }
    }

    static void GetDate()
    {
        var date = DateFormat("yyyyMMdd");
        Console.WriteLine(date);
    }
    static void GetTime() 
    {            
        var time = DateFormat("HHmmss");
        Console.WriteLine(time);
    }

    static string DateFormat(string format) 
    {
        var ci = new CultureInfo("ja-JP");
        var dt = DateTime.Now;
        return dt.ToString(format, ci);
    }    
}

使い方

ビルドしたexeを適当な場所に配置して、実行スクリプトから呼び出して変数にセットしています。

@echo off

for /F %%A IN ('GetDate.exe d') DO SET Dt=%%A
for /F %%A IN ('GetDate.exe t') DO SET Tm=%%A

set logfile="Sample_%Dt%%Tm%.log"
echo %Dt% %Tm% >> %logfile%

exit /b