I believe there are existing robust methods that rely on reading the registry. But many employees cannot access the registry on their workplace computers, so that is not a good solution.
The DosTips :Unique function gives a good start to a general solution. It can handle formats with the year, month, and date in any order. But it is dependent on the DATE command prompt using standard English date format tokens of yy, mm and dd. In the md and move Help experts thread aGerman pointed out to me how the tokens can vary by language. For example German uses JJ, MM and TT instead.
Below is my attempt at a "universal" date parser that does not require access to the registry. It currently supports English and German (or any other language that happens to use the same date tokens). It should be trivial to add support for additional languages by adding the appropriate token translation maps. I'm only able to test the English translation, but I think the German should work as well.
I'd like to hear from anyone who can contribute additional translation maps for the function.
I'm also keenly interested if anyone sees a problem with the code, has optimizations to contribute, or perhaps has an entirely different algorithm.
Of course any code can be broken if someone sets the date format to something out ot the ordinary. But I'm happy as long as the "universal" function supports "normal" formats.
Code: Select all
:parseDate yyVar mmVar ddVar
::
:: Parses %DATE% into numeric year, month, and date components
::
:: yyVar = name of variable to hold numeric year value
:: mmVar = name ov variable to hold numeric month value
:: ddVar = name of variable to hold numeric day value
setlocal enableDelayedExpansion
:: Parse the native date format tokens output by the DATE command
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('"echo:|date"') do (
rem Parse the numeric date components of %DATE%
for /f "tokens=1-3 delims=/.- " %%A in ("%date:* =%") do (
rem Set variables named after native date tokens to appropriate numeric date component values
set %%a=%%A
set %%b=%%B
set %%c=%%C
rem Create string of sorted native date format tokens
if %%a lss %%b if %%b lss %%c set "tokens=%%a %%b %%c"
if %%a lss %%c if %%c lss %%b set "tokens=%%a %%c %%b"
if %%b lss %%a if %%a lss %%c set "tokens=%%b %%a %%c"
if %%b lss %%c if %%c lss %%a set "tokens=%%b %%c %%a"
if %%c lss %%a if %%a lss %%b set "tokens=%%c %%a %%b"
if %%c lss %%b if %%b lss %%a set "tokens=%%c %%b %%a"
)
)
:: We now have variables with the correct values, but the code doesn't know
:: the name of the variables! We must translate the unknown native variable
:: names into known English names
:: Initialize the translation of native tokens to English tokens
set translate=
set T_yy=
set T_mm=
set T_dd=
:: Determine the correct token translation map
:: Each map in the for list should contain the space delimited English tokens
:: on the left followed by a semicolon followed by the space delimited native
:: tokens on the right. The native tokens should be sorted alphabetically
:: and the English tokens should be in the matching logical order.
:: Currently supports English and German. Additional translation maps
:: should be added for additional language support.
for %%t in (
"dd mm yy;dd mm yy"
"yy mm dd;JJ MM TT"
) do (
set test=%%~t
if "!test:*;=!"=="%tokens%" set translate=%%~t
)
:: Parse the token translation map into variables used for translation
for /f "tokens=1-6 delims=; " %%a in ("%translate%") do (
set T_%%a=%%d
set T_%%b=%%e
set T_%%c=%%f
)
:: Transfer the values from native date variables to English date variables
set E_yy=!%T_yy%!
set E_mm=!%T_mm%!
set E_dd=!%T_dd%!
:: Eliminate leading zeros so that numbers aren't interpreted as octal
set /a "E_yy=10000%E_yy% %%10000, E_mm=100%E_mm% %%100, E_dd=100%E_dd% %%100"
:: Return the date values
(endlocal
set %~1=%E_yy%
set %~2=%E_mm%
set %~3=%E_dd%
)
exit /b
Dave Benham