How to get Locale-independent modification date batch

batchdate-modifiedlocale

I need to get the modification date of a file stored in a variable like this: YearMonthDayHourMinute. So 01/21/2019 9:12 AM would be 201901210912. What I will be doing is comparing files to see which is newer, so it needs to be like this in 24 hour format. I was initially going to get it with this command: for %? IN ("%cd%\out.txt") do (echo %~t?) and use the for loop to split the output apart, but I was wondering if the modification date from a for loop is locale dependent like %date%? If it is, is there a way to check which type of format it is under, or is there a way to get a non-locale dependent modification date?

This is related to Why wont this function's variables set? Batch Code but I don't see how solving one would necessarily alter the other one, so I'm keeping them as separate questions.

Best Answer

set _ForString=%~1
set _ForString=!_ForString:\=\\!
For /f "tokens=1,2* delims==" %%a in ('wmic datafile where name="!_ForString!" get LastModified /format:list') do (
  echo %%a    %%b
  set %~2=%%b
)

Rem %1 is set to C:\Users\%username%\CMDS.bat

I'm actually getting the error C:\\Users\\theBATeam\\CMDS.bat - Invalid alias verb.

There are two problems in the above code snippet:

  • in name="!_ForString!": you need to escape the equals sign as name^="!_ForString!";
  • parsing wmic output in a FOR /F loop (explained below).

:ParseWmicDatafile subroutine in the following commented .bat script should do the job:

@ECHO OFF
SETLOCAL EnableExtensions

call :ParseWmicDatafile "%~f0" LastModified
REM show all variables prefixed with an underscore
set _

goto :eof

:ParseWmicDatafile
REM inputs (by value): %1 is a fully qualified file name 
REM                    %2 is a valid "wmic datafile" property name

REM outputs (by reference): _%~2 is a variable name drawn from supplied %2: 
REM                              property name prefixed with an underscore
REM                         _ForString

  REM remove residuary variable _%~2 (if present)
  if defined _%~2 set "_%~2="
  set "_ForString=%~1"
  set "_ForString=%_ForString:\=\\%"
  for /f "tokens=1* delims==" %%A in (
      'wmic datafile where name^="%_ForString%" get %~2 /format:list'
    ) do for /f "delims=" %%b in ("%%~B") do (
        echo %%A    %%b
        set "_%~2=%%b"
    )
goto :eof

Here the for loops are

  • %%A to retrieve the LastModified property name (%%A) and value (%%B);
  • %%b to remove the ending carriage return in the value returned; wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).

See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem

Output:

==> D:\bat\SU\1396664.bat
LastModified    20190201220347.477320+060
_ForString=D:\\bat\\SU\\1396664.bat
_LastModified=20190201220347.477320+060

==>
Related Question