2

I have this code in which I want to obtain the subtraction of a day from the current date, from 0 to -10, but I only correctly obtain the last one that is out of the cycle, any idea why?

echo off
Setlocal EnableDelayedExpansion

FOR /L %%A IN (0,1,10) DO (
    FOR /F "usebackq tokens=*" %%t IN (`powershell -NoProfile -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"`) DO (SET "START_DATE=%%t")
    echo START_DATE: %START_DATE%
)
echo START_DATE: %START_DATE%
Endlocal



pause

PopD
exit

and what I get in the terminal is this

echo off
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE:
START_DATE: 2020/07/22 11:07:06
Presione una tecla para continuar . . .
Adolfo Celis
  • 143
  • 2
  • 11
  • 2
    Does this answer your question? [Windows Batch Variables Won't Set](https://stackoverflow.com/questions/9681863/windows-batch-variables-wont-set) You've enabled delayed expansion, but you aren't using it. Use `!START_DATE!` instead of `%START_DATE%`. – SomethingDark Aug 01 '20 at 17:19

3 Answers3

0

You are not using delayedexpansion which you already enabled, but don't usebackq either as it is not needed.

@echo off & Setlocal EnableDelayedExpansion

FOR /L %%A IN (0,1,10) DO (
    FOR /F "tokens=*" %%t IN ('powershell -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"') DO (
    SET "START_DATE=%%t"
    echo START_DATE: !START_DATE!
 )
)
echo START_DATE: %START_DATE% 
Endlocal
pause
popd
exit

Note the ! intead of %. Which tells the system which variable you want to expand.

As a side note, you could get away without delayedexpansion if you simply want to echo the date/time in the loop.

@echo off
FOR /L %%A IN (0,1,10) DO (
    FOR /F "tokens=*" %%t IN ('powershell -Command "(Get-Date).AddDays(-%%A).ToString('yyyy/MM/dd HH:MM:ss')"') DO (
    SET "START_DATE=%%t"
    echo START_DATE: %%t
 )
)
echo START_DATE: %START_DATE% 
Endlocal
pause
PopD
exit
Gerhard
  • 22,678
  • 7
  • 27
  • 43
0

To get your required output in the cmd.exe window you don't need a at all, just a single one:

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile "for($i=0; $i -le 10; $i++){"(Get-Date).AddDays(-$i).ToString('START_DATE: yyyy/MM/dd HH:mm:ss')}"
@Pause

If you need to run it from a , because you need to perform additional work on each line of output then you should, once again, allow to perform most of the heavy lifting:

@For /F Delims^= %%G In ('^"
 "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
 "for($i=0; $i -le 10; $i++){(Get-Date).AddDays(-$i).ToString(`"^
 "'START_DATE: yyyy/MM/dd HH:mm:ss')}"^"')Do @Echo %%G
@Pause

This methodology could also be extended such that you can directly define the output as variables too, %Now[-1]%, %Now[-2]%, %Now[-3]% etc. This would give you a simple way to get your required format dates based upon the number of days ago; for example:

@For /F Delims^= %%G In ('^"
 "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
 "for($i=1; $i -le 10; $i++){(Get-Date).AddDays(-$i).ToString(`"^
 "\"Now[-$i]^=yyyy/MM/dd\")}"^"')Do @Set "%%G"
@Echo %Now[-6]%&Pause

The last line is obviously included just to show you what one of the defined variables would output.

Or based upon the simpler range method suggested by @lit in the comment section:

@For /F Delims^= %%G In ('^"
 "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile^
 "(0..-10)|%%{(Get-Date).AddDays($_).ToString(\"Now[$_]^=yyyy/MM/dd\")}"
 ^"')Do @Set "%%G"
@Echo %Now[0]%&Pause
Compo
  • 36,585
  • 5
  • 27
  • 39
  • Using a range would be even easier. `(0..-10) | ForEach-Object { (Get-Date).AddDays($_).ToString('yyyy/MM/dd HH:MM:ss') }` – lit Aug 01 '20 at 19:00
  • Yes @lit, point taken, however as the question was not really about powershell, my intention was to show that the powershell command need not run ten times in order to `do` 10 things, rather than how to more efficiently use powershell. I have added an additional example to the bottom of my answer, using that method. – Compo Aug 01 '20 at 19:20
0

This will not produce an array of environment variables like Compo's answer. But, I think it will do what the original question asked.

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -Command ^
     "(0..-10) | ForEach-Object { (Get-Date).AddDays($_).ToString('yyyy/MM/dd') }"
@pause
lit
  • 14,456
  • 10
  • 65
  • 119