Format file date YYYYMMDD in batch

2019-07-15 09:53发布

I've been working on some code in a batch file that evaluates two file dates. If one date is greater than the other then it runs another bat file. What I want to do is format the two dates as YYYYMMDD so that I can use the GTR (greater than).

The code is below but and it works if I use == (equal) because it's evaluating the string. I only want to know if one file date is greater than the other file date.

I'm not asking for someone to amend the code below but if you can show me how to format the dates I would be very grateful.


set Fileone=File1.txt
set FileTwo=File2.txt

pushd "D:\Board\Broadcast\FA_Report8_A"
FOR %%f IN (%FileOne%) DO SET filedatetime=%%~tf
FOR %%f IN (%FileTwo%) DO SET filedatetime2=%%~tf
SET filedatetime2=%year%%month%%day%
IF %filedatetime:~0, 10% GTR %filedatetime2:~0, 10% ( 
echo FileOne Greater - run bat
timeout /t 20 /nobreak
goto Finish
) else (
echo FileOne not Greater - Finish
goto Finish
)
:Finish
echo finished 
pause

3条回答
We Are One
2楼-- · 2019-07-15 10:19

The layout for date variable strings in the system can be assumed by settings from the user, by regional and/or language, so, date is not 100% predictable layout to work with.


Try using wmic OS Get localdatetime /value because the result is 100% predictable:

LocalDateTime=20190609123708.733000-180

SO, if you use in for loop, adding 2 delimiters like =., (equal and dot), you go getting this string output:

20190609123708.

The layout from this command is predictable and works independent of regional settings, user settings or system language, so, the command will always return:

set _date=20190609123708
rem :: %_date:~0,4%_%_date:~4,2%_%_date:~6,2%
rem ::   year:2019 |  month:06  | day:09

In bat file:

 @echo off & for /f "tokens=2delims==." %%i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_date=%%i" & echo/%_date:~0,4%%_date:~4,2%%_date:~6,2%

In command line:

for /f "tokens=2delims==." %i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_data=%i" & mkdir %_date:~0,4%_%_date:~4,2%_%_date:~6,2%

This commands result ::

    20190609


May I can also suggest:

wmic Path Win32_LocalTime Get Day,Month,Year 

In looping for:

@echo off & setlocal enabledelayedexpansion & set "_do=wmic Path Win32_LocalTime Get Day^,Month^,Year" 
for /f "tokens=1-3delims= " %%a in ('!_do!^|findstr /r [0-9]')do set "y=%%c" & set "d=0%%a" & set "m=0%%b"
echo/!y!!m:~-2!!d:~-2! >nul 

Result:

Day  Month  Year
 9   6      2019 
%%a  %%b    %%c

The difference is no zero in number for month/day less equal 9, so, you can use this bat to put leading zero in this case:

@echo off & setlocal enabledelayedexpansion & set "_do=wmic Path Win32_LocalTime Get Day^,Month^,Year" 
for /f "tokens=1-3delims= " %%a in ('!_do!^|findstr /r [0-9]')do set "y=%%c" & set "d=0%%a" & set "m=0%%b"
echo/!y!!m:~-2!!d:~-2!

Result in YearMonthDay:

20190609

Obs.: In PowerShell, the layout can be customized simple by:

ToString("yyyyMMdd")

The strings can be set with ToString.

Sample: yyyy-MM-dd, dd-MM-yyyy, MM-dd-yyyy, MM_dd_yyyy, yyyy_MM_dd, etc..


The Powershell command:

$(Get-Date).ToString("yyyyMMdd")

Result:

2010609

See more about date variable layout output in batch here:

Safe way to get current day month and year in batch

Parsing Dates in Batch Files & Regional Settings / Locale



Update - How applying the comments/observations above in your bat, so, if I understood your code in this question:


@echo off & setlocal enabledelayedexpansion 

set "Fileone=File1.txt" &  set "FileTwo=File2.txt"

set "_both=!FileOne!-!FileTwo!" & rem cd /d "D:\Board\Broadcast\FA_Report8_A"

set "_path_back=%__CD__%" & rem :: you can use this "%__CD__%" or pushd "D:\Board\Broadcast\FA_Report8_A" 

for /f "tokens=2delims==." %%i in ('wmic OS Get localdatetime /value ^|findstr /r [0-9]')do set "_date=%%i"

set _now=!_date:~0,4!!_date:~4,2!!_date:~6,2! & for /f "tokens=1*delims=-" %%i in ('echo/!_both!')do (

     call :compare "%%~fi" & call :compare "%%~fj" & if !_dt_file_2! gtr !_dt_file_2! ( 

         echo/ FileOne Greater - run bat & timeout /t 20 /nobreak & goto :run_bat

         ) else (echo/ FileOne not Greater - Finish & goto Finish) 

    )

:compare
set "_file="  & set "_file=%~1" 

for /f "tokens=1delims=. " %%d in ('wmic datafile where name^='!_file:\=\\!' get LastModified ^|findstr /v "LastModified"')do (

    if "!_dt_file_1!./" == "./" (set _dt_file_2=%%d) else (set _dt_file_2=%%d)

    ) & exit /b

:run_bat 
call the_bat_to_run.cmd 

:Finish
echo/Finished

So sorry by my limited English...

查看更多
甜甜的少女心
3楼-- · 2019-07-15 10:22

It's not portable between machines with different date formats but the simplest way is to use a substring: %var:~STARTPOS,LENGTH%

set filedatetime=14/06/2012 12:26
set filedatetime=%filedatetime:~6,4%%filedatetime:~3,2%%filedatetime:~0,2%
echo "%filedatetime%"

"20120614"
查看更多
爷、活的狠高调
4楼-- · 2019-07-15 10:22

You can separate a date in its parts with a FOR /F command:

set filedatetime=14/06/2012 12:26
for /F "tokens=1-3 delims=/ " %%a in ("%filedatetime%") do (
   set filedatetime=%%c%%b%%a
)

This form prevents you to make a mistake in the position or size of each substring, and is very easy to change the order of the parts. For example, if your date is MM/DD/YYYY:

set filedatetime=%%c%%a%%b

Type FOR /? for further details.

查看更多
登录 后发表回答