2016-12-07 22 views
0

バッチスクリプトで4日前の日付を生成したいと思います。私は利用可能なソリューションをチェックしましたが、それはとても複雑に見えます。どんな助けもありがとう。バッチスクリプトで日付を4日前に生成するにはどうすればよいですか?

+2

あなたが求めていることは明確ではありません。少なくとも、あなたの質問には「とても複雑な」解決策をいくつか追加して、pplはあなたが達成しようとしているものを見ます。 –

+0

現在の日付の4日前? – npocmaka

+2

'バッチファイル'スクリプト**は、 'cmd'が日時の操作をネイティブにサポートしていないので、複雑すぎるように見える必要があります。これは文字列と整数算術のみをサポートします。さらなる複雑さ:日付と時刻のパターンは、(ユーザーの)ロケール設定に大きく依存します。 – JosefZ

答えて

3

@JosefZと強く同意します。日付の計算は複雑な問題です。 VBScriptとPowerShellはそれを組み込み、それはブラックボックスのように使用され、依存しています。
バッチに32ビット符号付き整数しかない場合でも、これを解決するには十分です。バッチの終わりに格納された呼び出し可能なサブルーチンにパッケージ化されている場合、多くのことを苛立たせるべきではありません。

パスのどこかにバッチライブラリに配置する方法さえあり、それらを呼び出すには小さなスタブしか必要ありません。
バッチコード(PowerShellの1つのライナーと比較して大量のオーバーヘッドを持つ)のみのバリアントです。日付の形式と言語に制限はありません。

出力:

Today Year: 2016 Month: 12 Day: 08 
-38 Year: 2016 Month: 10 Day: 31 

バッチ

@Echo off 
Call :GetDate yy mm dd 
Echo Today Year: %yy% Month: %mm% Day: %dd% 
Set /A n=-38 
Call :DateAdd yy mm dd %n% 
Echo %n% Year: %yy% Month: %mm% Day: %dd% 
Pause 
Goto :Eof 

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
:GetDate yy mm dd 
:: 
:: Func: Loads local system date components into args 1 to 3. 
:: 
:: Args: %1 var to receive year,     4 digits (by ref) 
::  %2 var to receive month,  2 digits, 01 to 12 (by ref) 
::  %3 Var to receive day of month, 2 digits, 01 to 31 (by ref) 
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
SetLocal EnableExtensions 
for /f "tokens=1-3 delims=.+-" %%A in (
    'wmic os get LocalDateTime^|findstr ^^[0-9]' 
    ) do Set _DT=%%A 
Set "yy=%_DT:~0,4%"&Set "MM=%_DT:~4,2%"&Set "dd=%_DT:~6,2%" 
endlocal&set %1=%yy%&set %2=%MM%&set %3=%dd%&goto :EOF 
:: GetDate.cmd ::::::::::::::::::::::::::::::::::::::::::::::::::::: 
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
:DateAdd yy mm dd #days 
:: 
:: Func: Adds/subs Days from/to a given date by converting to a 
::  Julian Day adding the offset and converting back. 
:: Args: 
:: %1 year component used to create JD,  4 digits (by ref) 
:: %2 month component used to create JD, leading zero ret (by ref) 
:: %3 day of month used to create MJD, leading zero ret (by ref) 
:: %4 days offset may be positive or negative (by val) 
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
SetLocal 
Call set /A "yy=%%%1%%,mm=100%%%2%% %%%%100,dd=100%%%3%% %%%%100" 
Set /A jd=(1461*(yy+4800+(mm-14)/12))/4 
Set /A jd=jd+(367*(mm-2-12*((mm-14)/12)))/12 
Set /A jd=jd-(3*((yy+4900+(mm-14)/12)/100))/4,jd=jd+dd-32075 
Set /A jd=jd+%4 
set /A l=jd+68569,n=(4*l)/146097,l=l-(146097*n+3)/4 
Set /A i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31,j=(80*l)/2447 
Set /A dd=l-(2447*j)/80,l=j/11,mm=j+2-(12*l),yy=100*(n-49)+i+l 
(if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%) 
Endlocal&set %1=%yy%&set %2=%mm%&set %3=%dd%&Goto :Eof 
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 
2

.bat拡張子でこれを保存します。厳格なバッチでこれを行うには

@if (@x)==(@y) @end /***** jscript comment ****** 
    @echo off 
    cscript //E:JScript //nologo "%~f0" "%~nx0" 
    exit /b %errorlevel% 

@if (@x)==(@y) @end ****** end comment *********/ 

var d = new Date(); 
d.setDate(d.getDate()-4); 
WScript.Echo("berfore 4 days : "+d); 
2

、あなたは%date%にトークン化または部分抽出を使用する必要があります。ただし、ロケール設定などの変更により問題が発生します。前述のように、月、年、閏年、夏時間などを考慮してバッチの計算を理解していないため、別の日付に基づいて相対日付を取得したい場合はさらに問題になります。

So最良の答えは、通常、別の答えでJScriptのような外部の言語やライブラリ、または私の好きなもの、Powershellに依存することです。

for /f %%a in ('"powershell [DateTime]::Now.AddDays(-4).ToString('dd-MMM-yy')"') do echo %%a 

これはPowerShellの日付を取得するワンライナーは、4日減算し、%%aとしてDD-MMM-yy形式でそれを入れています。 %%aで何でもできますし、好きなようにフォーマットを変更できます。

+0

'for'コマンドはここでは使用できません。これは日付をバッチ変数に入れます: 'set a = powershell(Get-Date).AddDays(-4).ToString( 'dd-MMM-yy')' – xXhRQ8sD2L7Z

+2

正確ではありません。それはコマンド文字列を変数に入れて実行する必要がありますが、依然として結果は変数にはありません。 – soja

+0

うん、良いコール@soja。環境変数を調べると、powershellコマンドが実行され、結果が得られました。しかし、あなたが正しいです、結果自体はバッチ変数にありません。 – xXhRQ8sD2L7Z

2

はい、ユリウス日番号に変換し、日数を減算し、結果を元に戻す複雑な純粋なバッチファイルメソッドがあります。また、PowerShellやVBScript/JScriptなどの他のプログラミング言語の日付関数を使用する他の方法もあります。

以下の6行の純バッチメソッドがあまり複雑にならないことを願っています。この方法は、MM/DD/YYYYの%DATE%形式で動作

@echo off 
setlocal EnableDelayedExpansion 

set N=4 

set i=100 
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do set /A "i+=1" & set "dpm[!i!]=%%a" 
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
    set /A "DD=1%%b-N, I=^!(((DD-101)>>31)+1), MM=1%%a-I, J=^!(MM-100), MM+=J*12" 
    set /A "YYYY=%%c-J, dpm[102]+=^!(YYYY%%4), DD+=I*dpm[!MM!]" 
) 
set "newDate=%MM:~1%/%DD:~1%/%YYYY% 

echo %newDate% 

。あなたの日付形式が異なる場合は、式の中で%%a%%bのパラメータの位置を変更し、結果にはMMDDの順番を変更してください。

この方法では、現在の日付から最大1か月を差し引くことができます。

+1

私はOPが「複雑です」と「私は理解できません」と思っています。この場合、おそらくこの答えは「複雑」です.-あなたは100,400閏年のルールを考慮していませんでした。コード(バッチ)がおそらく80年以上も生き残っていない可能性があるため、現在の日付のみを処理する場合は問題にはならない可能性があります。しかし、誰かがこのアルゴリズムを利用してユーザーが入力した日付に適用すると、1900年、2100年などの間にいくつかの誤った答えが得られます。 – dbenham

0

ここでは、日付マイナスの日数を取得するためのもう一つの複雑なバッチ方法です。これは、XCOPYでトリックを使用して日付が有効であることを検証します。

@echo off 
setlocal 
set rand=%random% 
md "dummy%rand%\empty%rand%" 

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a" 

set /a y=%dt:~0,4% 
set /a m=1%dt:~4,2% 
set /a d=1%dt:~6,2% 

REM set the number of days to substract 
SET DAYS=4 
FOR /L %%G IN (1,1,%days%) DO CALL :loop 

set subdate=%y%%m:~-2%%d:~-2% 
echo %subdate% 

rd /s /q "dummy%rand%" 
pause 
endlocal 
GOTO :EOF 

:loop 
    set /a d-=1 

    if %d% lss 101 (
    set d=131 
    set /a m-=1 

    if %m% lss 101 (
     set m=112 
     set /a y-=1 
    ) 
) 

xcopy /d:%m:~-2%-%d:~-2%-%y% /t "dummy%rand%\empty%rand%" "dummy%rand%" >nul 2>&1 || goto loop 

GOTO :EOF 
関連する問題