Windowsバッチ:日付を変数にフォーマット


105

現在の日付をYYYY-MM-DD形式でWindows .batファイルの変数に保存するにはどうすればよいですか?

Unixシェルアナログ:

today=`date +%F`
echo $today



1
adarshr、その質問への答えは、それに対処するために非常に恐ろしく、エラーが発生しやすい方法を使用しています。使用しないことをお勧めします。
Joey

このリンクは、以下の回答を理解するのに役立ちます。ss64.com/nt/for_f.html
smwikipedia

回答:


151

現在の日付は、ロケールにとらわれない方法で取得できます。

for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x

次に、部分文字列を使用して個々の部分を抽出できます。

set today=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%

個別の部分を含む変数を取得する別の方法は、次のとおりです。

for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

変数の名前空間を汚染することを犠牲にして、部分文字列をいじるよりもはるかに優れています。

現地時間ではなくUTCが必要な場合、コマンドはほぼ同じです。

for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
set today=%Year%-%Month%-%Day%

1
@ user2023861コマンドプロンプトを開いた場合でも、コマンドプロンプトを開いたときではなく、コマンドの呼び出し時に常に正しい日付/時刻を取得しているようです。
ADTC 2013

5
上記の行を複数回実行すると、変数が未定義であるかどうかがチェックされるため、呼び出しごとに新しい日付が取得されないことに注意してください。for /f後者は空の行である2行を返すため、これが必要です。あなたはset MyDate=その間に使用することでそれを解決することができます。それはuser2023861がつまずいたことだと思います。
ジョーイ

1
@CharlesWood、少なくとも私は自分のバッチファイルの堅牢性を追求していますが、最近では代わりにPowerShellを使用することがよくあります。
Joey

1
:設定された変数YearMonthDayHourMinuteSecondQuarterWeekInMonthDayOfWeek
ユーザー

2
for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set today=%Year%-%Month%-%Day% 不正解です。1桁の月と日を返します。2桁の左にゼロの月と日の日付の文字列を埋め込む方法は?
Andrus

38

バッチファイルで標準のMS-DOSコマンドを使用してこれを実現したい場合は、以下を使用できます。

FOR /F "TOKENS=1 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET dd=%%A
FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
FOR /F "TOKENS=1,2,3 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET yyyy=%%C

これはさらに改善できると確信していますが、これは日付を日(dd)、月(mm)、年(yyyy)の3つの変数に与えます。必要に応じて、これらを後でバッチスクリプトで使用できます。

SET todaysdate=%yyyy%%mm%%dd%
echo %dd%
echo %mm%
echo %yyyy%
echo %todaysdate%

私はこの質問に対する回答が受け入れられたことを理解していますが、この代替方法は、WMIコンソールを使用せずにこれを達成しようとする多くの人から評価される可能性があります。


3
Windows 7のボックスでこれを少し変更する必要があることがわかりました。トークンは1ずつインクリメントする必要がありました:... FOR / F "TOKENS = 2,3,4 eol = / DELIMS = /" ...
Joe Johnston

1
AzureのWindows Server 2012でも同じ
Kirill Yunussov

34

date /Tコマンドプロンプトで形式を見つけるために使用します。

日付形式が次のThu 17/03/2016ように使用されている場合:

set datestr=%date:~10,4%-%date:~7,2%-%date:~4,2%
echo %datestr%

1
これは、質問に最も近い回答です。プログラムではなく、単純なワンライナーで十分でした。
DCookie 2016年

2
同意した。ここでの回答の一部は、「MS SQL Serverをインストールし、SQLクライアントに接続して、コマンドを実行する」のように見えますSELECT CONVERT(VARCHAR(16), GETDATE(), 112)
isapir 2017年

2
ISO-8601形式の日時は%date:~10,4%%date:~7,2%%date:~4,2%T%time:~0,2%%time:~3,2%%time:~6,2%
isapir

3
他の応答がプログラムのように見える理由は、この応答は単純ですが、このコードが期待する方法でWindowsの地域設定が構成されていないと失敗するためです(つまり、このコードはすべての Windowsシステムで機能しません)
Daniel Scott

20

時間設定に依存しない2つの方法(どちらもローカリゼーションから独立したデータ/時間の取得方法から取得)。また、どちらも曜日を取得し、管理者権限を必要としません!:

  1. MAKECAB-すべての Windowsシステムで動作します(高速ですが、小さな一時ファイルが作成されます)(foxidriveスクリプト):

    @echo off
    pushd "%temp%"
    makecab /D RptFileName=~.rpt /D InfFileName=~.inf /f nul >nul
    for /f "tokens=3-7" %%a in ('find /i "makecab"^<~.rpt') do (
        set "current-date=%%e-%%b-%%c"
        set "current-time=%%d"
        set "weekday=%%a"
    )
    del ~.*
    popd
    echo %weekday% %current-date% %current-time%
    pause
    
  2. ROBOCOPY - Windows XPおよびWindows Server 2003のネイティブコマンドではありませんが、Microsoftのサイトからダウンロードできます。しかし、Windows Vista以降のすべてに組み込まれています。

    @echo off
    setlocal
    for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (
        set "dow=%%D"
        set "month=%%E"
        set "day=%%F"
        set "HH=%%G"
        set "MM=%%H"
        set "SS=%%I"
        set "year=%%J"
    )
    
    echo Day of the week: %dow%
    echo Day of the month : %day%
    echo Month : %month%
    echo hour : %HH%
    echo minutes : %MM%
    echo seconds : %SS%
    echo year : %year%
    endlocal
    

    その他のWindowsスクリプト言語を使用する3つの方法。それらはあなたにもっと柔軟性を与えます。例えば、あなたは年間の週、ミリ秒の時間などを得ることができます。

  3. JScript / BATCHハイブリッド(として保存する必要があります.bat)。JScriptは、Windows Script Hostの一部として、Windows NT以降のすべてのシステムで使用できます(ただし、レジストリを使用して無効にすることはまれです)。

    @if (@X)==(@Y) @end /* ---Harmless hybrid line that begins a JScript comment
    
    @echo off
    cscript //E:JScript //nologo "%~f0"
    exit /b 0
    *------------------------------------------------------------------------------*/
    
    function GetCurrentDate() {
        // Today date time which will used to set as default date.
        var todayDate = new Date();
        todayDate = todayDate.getFullYear() + "-" +
                       ("0" + (todayDate.getMonth() + 1)).slice(-2) + "-" +
                       ("0" + todayDate.getDate()).slice(-2) + " " + ("0" + todayDate.getHours()).slice(-2) + ":" +
                       ("0" + todayDate.getMinutes()).slice(-2);
    
        return todayDate;
    }
    
    WScript.Echo(GetCurrentDate());
    
  4. VBScript / BATCHハイブリッド(一時ファイルを使用せずにバッチファイル内にVBScriptを埋め込み、実行することは可能ですか?)jscriptと同じケースですが、ハイブリッド化はそれほど完璧ではありません。

    :sub echo(str) :end sub
    echo off
    '>nul 2>&1|| copy /Y %windir%\System32\doskey.exe %windir%\System32\'.exe >nul
    '& echo current date:
    '& cscript /nologo /E:vbscript "%~f0"
    '& exit /b
    
    '0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if specified: hh:mm:ss PM/AM.
    '1 = vbLongDate - Returns date: weekday, monthname, year
    '2 = vbShortDate - Returns date: mm/dd/yy
    '3 = vbLongTime - Returns time: hh:mm:ss PM/AM
    '4 = vbShortTime - Return time: hh:mm
    
    WScript.echo  Replace(FormatDateTime(Date, 1), ", ", "-")
    
  5. PowerShell-.NETがインストールされているすべてのマシンにインストールできます-Microsoftからダウンロードします(v1v2、およびv3(Windows 7以降のみ))。Windows 7 / Win2008以降のすべてにデフォルトでインストールされます。

    C:\> powershell get-date -format "{dd-MMM-yyyy HH:mm}"
    
  6. 自己コンパイルされたjscript.net/batch(.NETなしのWindowsマシンを見たことがないので、これはかなり移植性があると思います):

    @if (@X)==(@Y) @end /****** silent line that start jscript comment ******
    
    @echo off
    ::::::::::::::::::::::::::::::::::::
    :::       Compile the script    ::::
    ::::::::::::::::::::::::::::::::::::
    setlocal
    if exist "%~n0.exe" goto :skip_compilation
    
    set "frm=%SystemRoot%\Microsoft.NET\Framework\"
    :: searching the latest installed .net framework
    for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
        if exist "%%v\jsc.exe" (
            rem :: the javascript.net compiler
            set "jsc=%%~dpsnfxv\jsc.exe"
            goto :break_loop
        )
    )
    echo jsc.exe not found && exit /b 0
    :break_loop
    
    
    call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0"
    ::::::::::::::::::::::::::::::::::::
    :::       End of compilation    ::::
    ::::::::::::::::::::::::::::::::::::
    :skip_compilation
    
    "%~n0.exe"
    
    exit /b 0
    
    
    ****** End of JScript comment ******/
    import System;
    import System.IO;
    
    var dt=DateTime.Now;
    Console.WriteLine(dt.ToString("yyyy-MM-dd hh:mm:ss"));
    
  7. Logmanこれは年と曜日を取得できません。これは比較的低速で、一時ファイルも作成し、logmanがログファイルに書き込むタイムスタンプに基づいています。WindowsXP以降のすべてを動作させます。それはおそらく私を含む誰もが使用することはないでしょうが、もう1つの方法です...

    @echo off
    setlocal
    del /q /f %temp%\timestampfile_*
    
    Logman.exe stop ts-CPU 1>nul 2>&1
    Logman.exe delete ts-CPU 1>nul 2>&1
    
    Logman.exe create counter ts-CPU  -sc 2 -v mmddhhmm -max 250 -c "\Processor(_Total)\%% Processor Time" -o %temp%\timestampfile_ >nul
    Logman.exe start ts-CPU 1>nul 2>&1
    
    Logman.exe stop ts-CPU >nul 2>&1
    Logman.exe delete ts-CPU >nul 2>&1
    for /f "tokens=2 delims=_." %%t in  ('dir /b %temp%\timestampfile_*^&del /q/f %temp%\timestampfile_*') do set timestamp=%%t
    
    echo %timestamp%
    echo MM: %timestamp:~0,2%
    echo dd: %timestamp:~2,2%
    echo hh: %timestamp:~4,2%
    echo mm: %timestamp:~6,2%
    
    endlocal
    exit /b 0
    

Get-Date関数の詳細



8

ジョーイの方法は本当に好きでしたが、少し拡張したいと思いました。

このアプローチでは、コードが複数回実行され、古い日付値が既に定義されているため、「こだわる」ことを心配する必要がありません。

このバッチファイルを実行するたびに、ISO 8601互換の日付と時刻の組み合わせが出力されます。

FOR /F "skip=1" %%D IN ('WMIC OS GET LocalDateTime') DO (SET LIDATE=%%D & GOTO :GOT_LIDATE)
:GOT_LIDATE
SET DATETIME=%LIDATE:~0,4%-%LIDATE:~4,2%-%LIDATE:~6,2%T%LIDATE:~8,2%:%LIDATE:~10,2%:%LIDATE:~12,2%
ECHO %DATETIME%

このバージョンでは、同じコードをファイル内の複数の場所にコピー/貼り付けしないように注意する必要があります。ラベルが重複するためです。コピーごとに個別のラベルを付けるか、このコードを独自のバッチファイルに入れて、必要に応じてソースファイルから呼び出すことができます。


5

%date%変数を使用するだけです:

echo %date%

5
これにより、現在構成されている短い日付形式の日付が返されます。これはめったにISO-8601ではありません。
ジョーイ

@Joey Agreed-これは信頼するのに十分ではないので私はここにいます。
SteveCinq 2018年

5

@ProViの回答に従って、必要なフォーマットに合わせて変更してください

echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%

戻ります

yyyy-MM-dd hh:mm:ss
2015-09-15 18:36:11

編集 @Jebコメントによると、上記の時刻形式が正しいのは、DATE / Tコマンドが返された場合にのみ機能します。

ddd dd/mm/yyyy
Thu 17/09/2015

ロケールに合わせて編集するのは簡単ですが、関連する%DATE%環境変数によって返される文字列の各文字のインデックスを使用することで、必要な文字列の部分を抽出できます。

例えば。%DATE〜10,4%を使用すると、DATE環境変数が展開され、展開された結果の11番目(オフセット10)の文字で始まる4文字のみが使用されます

たとえば、米国スタイルの日付を使用している場合、次が適用されます

ddd mm/dd/yyyy
Thu 09/17/2015

echo %DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2% %TIME:~0,2%:%TIME:~3,2%:%TIME:~6,2%
2015-09-17 18:36:11

これは、日付/時刻形式の設定に応じて、世界の一部の場所でのみ機能するため、一部の人にとってはソリューションにすぎません
jeb

3

これを行うことにより、環境変数を数値形式の値に設定します。

FOR /F "tokens=1,2,3,4 delims=/ " %a IN ('echo %date%') DO set DateRun=%d-%b-%c

2

これをチェック

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause

2

Pythonがインストールされている場合は、

python -c "import datetime;print(datetime.date.today().strftime('%Y-%m-%d'))"

フォーマット文字列はニーズに合わせて簡単に調整できます。


2
質問への回答として「Pythonを使用する」とはどういう意味ですか。
ロスプレッサー2017

3
MAKECAB、ROBOCOPY、VBSCRIPT、POWERSHELL Logmanを使用するのと同じように、コマンドラインで呼び出すことができる他の提案はここにありますか?
CodeKid 2017

クラスpython -c "import datetime;print(datetime.date.today())"__str__メソッドがをdate呼び出すだけなので、これはに簡略化できますisoformat()
onewhaleid

2

PowerShellを使用し、ループを使用してその出力を環境変数にリダイレクトすることが可能です。

コマンドライン(cmd)から:

for /f "tokens=*" %a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%a

echo %td%
2016-25-02+17:25

バッチファイルでは、エスケープ可能性がある%aとして%%a

for /f "tokens=*" %%a in ('powershell get-date -format "{yyyy-MM-dd+HH:mm}"') do set td=%%a

1
マスクはこのFOR /F "tokens=*" %%a IN ('powershell get-date -format "{yyyy\-MM\-dd\THH\:mm\:ss}"') DO SET date=%%a ようにする必要があるため、月には上部MMを使用し、リテラル文字をエスケープするにはバックスラッシュを使用します。
Whome 2016年

1

日付と時刻の形式は場所固有の情報であるため、%date%変数と%time%変数から取得するには、形式変換を考慮して文字列を解析するための追加の作業が必要になります。APIを使用してデータ構造を取得し、必要に応じて解析することをお勧めします。WMICは良い選択です。以下の例ではWin32_LocalTimeを使用しています。Win32_CurrentTimeまたはWin32_UTCTimeを使用することもできます。

@echo off  
SETLOCAL ENABLEDELAYEDEXPANSION  
for /f %%x in ('wmic path Win32_LocalTime get /format:list ^| findstr "="') do set %%x  
set yyyy=0000%Year%  
set mmmm=0000%Month%  
set dd=00%Day%  
set hh=00%Hour%  
set mm=00%Minute%  
set ss=00%Second%  
set ts=!yyyy:~-4!-!mmmm:~-2!-!dd:~-2!_!hh:~-2!:!mm:~-2!:!ss:~-2!  
echo %ts%  
ENDLOCAL  

結果:
2018-04-25_10:03:11


1

これは、時間を含み、パーツに0を埋め込むJoeyの回答の拡張です。

たとえば、結果は2019-06-01_17-25-36になります。また、これはUTC時間であることに注意してください。

  for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x

  set Month=0%Month%
  set Month=%Month:~-2%
  set Day=0%Day%
  set Day=%Day:~-2%
  set Hour=0%Hour%
  set Hour=%Hour:~-2%
  set Minute=0%Minute%
  set Minute=%Minute:~-2%
  set Second=0%Second%
  set Second=%Second:~-2%

  set TimeStamp=%Year%-%Month%-%Day%_%Hour%-%Minute%-%Second%


0

私は以下を使用しています:

set iso_date=%date:~6,4%-%date:~3,2%-%date:~0,2%

または、ログファイル名「MyLogFileName」と組み合わせて:

set log_file=%date:~6,4%-%date:~3,2%-%date:~0,2%-MyLogFileName

2
しかし、あなたの答えは他の16とどこが違うか、またはより良いですか?そして、すでに十分なヒントがあり、このソリューションはローカリゼーションでのみ機能する
jeb

0

powershellが利用可能な場合は、以下のコードを使用できます。

# get date
$BuildDate=(get-date -format "yyMMdd")
echo BuildDate=$BuildDate

# get time
$BuildTime=(get-date -format "hhmmss")
echo BuildTime=$BuildTime

結果は次のとおりです。

BuildDate=200518
BuildTime=115919

-2

(Windowsの地域設定に依存しない)信頼性の高いソリューションを取得するために10〜30分の1回の投資を気にしない場合は、以下をお読みください。

心を解放しましょう。このようにスクリプトを単純化しますか?(LOG_DATETIME変数を設定するとします)

FOR /F "tokens=* USEBACKQ" %%F IN (`FormatNow "yyyy-MM-dd"`) DO (
  Set LOG_DATETIME=%%F
)

echo I am going to write log to Testing_%LOG_DATETIME%.log

あなたはできる。C#.NETを使用してFormatNow.exeをビルドし、PATHに追加するだけです。

ノート:

  1. Visual Studio Expressなどの任意のVisual Studioエディションを使用して、FormatNow.exeをビルドできます。
  2. Visual Studioで、「Windowsフォームアプリケーション」プロジェクトではなく、「コンソールアプリケーション」C#プロジェクトを選択します。
  3. 常識:ビルドされたFormatNow.exeを実行するには、.NET Frameworkが必要です。
  4. 常識:FormatNow.exeをPATH変数に追加した後、有効にするためにCMDを再起動する必要があります。また、環境変数の変更にも適用されます。

利点:

  1. 遅くはありません(0.2秒以内に終了します)。
  2. 多くの形式がサポートされていますhttps://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx 例えばFormatNow、FormatNow「YYYY」のみ取得するには、週の日だけを取得するには「DDD」年
  3. Windowsの地域設定に依存しないため、出力の信頼性が大幅に向上します。一方、%date%は異なるコンピューター上で一貫した形式を提供せず、信頼性がありません。
  4. それほど多くのCMD変数を作成して、変数の名前空間を汚染する必要はありません。
  5. プログラムを呼び出して結果を取得するには、バッチスクリプトに3行必要です。それは十分に短いはずです。

Visual Studio 2010を使用してビルドしたFormatNow.exeのソースコード(未知の、おそらくは悪意のあるプログラムをダウンロードするリスクを回避するために、自分でビルドすることを好みます)。以下のコードをコピーして貼り付け、プログラムを1回ビルドするだけで、将来のすべての使用のための信頼できる日付フォーマッターが得られます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace FormatNow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length < 1)
                {
                    throw new ArgumentException("Missing format");
                }
                string format = args[0];
                Console.Write(DateTime.Now.ToString(format, CultureInfo.InvariantCulture.DateTimeFormat));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

    }
}

一般に、複雑なロジックを処理する場合は、非常に小さなプログラムを作成し、代わりにプログラムを呼び出して出力をキャプチャしてバッチスクリプト変数に戻すことで、をより簡単にすることができます。私たちは学生ではなく、問題を解決するためにバッチスクリプトのみのルールに従うことを要求する試験を受けていません。実際の作業環境では、任意の(法的)メソッドが許可されます。多くの単純なタスクの回避策を必要とするWindowsバッチスクリプトの貧弱な機能を引き続き使用する必要があるのはなぜですか?なぜ私たちは仕事に間違ったツールを使うべきなのでしょうか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.