1.

Solve : create an exact copy with date in batch file?

Answer»

Hi,

I have a question and try to make it simple. I want to create a batch for backup purposes.

The source is C:\Data

The destination is E:\

I'd like to create a directory called Data in E drive with the date next to it, for example Data 20 September 2011. The format of the date does not really matter.

So far I have got the following
@ECHO off
robocopy "C:\Data" "E:\..." /MIR
pause

I want to be able to make another exact copy of the folder "Data" and call it "Data" with date attached to it.

Any help would be greatly appreciated.

Thank youuse %date% variable wherever you want

robocopy "C:\Data" "E:\Data%date%\" /MIR

should work, if not its something like thatQuote from: a117yogi on June 03, 2011, 02:01:04 PM

use %date% variable wherever you want

This is nonsense if %date% contains slashes. Like "03/06/2011". Which is what %date% says here.

Quote
should work, if not its something like that

Please do not post wild guesses. Or "something like that". Just tested solutions. Ones that work.
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do robocopy "C:\Data" "E:\data-%%e-%%f-%%g" /MIR

better?Quote from: a117yogi on June 03, 2011, 03:32:24 PM
for /f "tokens=1-5 delims=/ " %%d in ("%date%") do robocopy "C:\Data" "E:\data-%%e-%%f-%%g" /MIR

better?

OK, but why don't you address the issue of differing local date formats?
This getdate batch comes in handy to determine the date fields without having to read the REGISTRY:
Here is my version of GetDate.bat. I've tried it in all the 'English' date formats in XP, Vista, Win7.
If you pass the name of an environment variable ( no %'s in the argument) it will get set to the current date.
yyyymmdd is returned in the errorlevel as a number but it can be used as %ymd% for an 8 digit date with no separaters.

Code: [Select]@echo off&SetLocal EnableDelayedExpansion&goto :start
:GetDate.bat [EnVar]
echo.GetDate [EnVar] Sets date into environment variable, EnVar as: mm-dd-yyyy
echo.Usage: GetDate mdy^&set ymd=%%errorlevel%%, ^(use %% rather than ^^! in command line)
echo.Usage: GetDate mdy^&set ymd=^^!errorlevel^^!, ^(use ^^! rather than %% in script^)
echo.If no argument passed it echo's the date in mm-dd-yyyy format
echo.Returns yyyymmdd in errorlevel regardless if Envar is passed as argument or not
echo.Works on any NT/2K/XP/Vista/Win7 machine independent of regional date settings
EndLocal&exit /b
:start
set p1=%~1&if /i !p1! equ /? goto :GetDate
for /f "tokens=1-4 delims=/-. " %%a in ("%date%") do call :s_fixdate %%a %%b %%c %%d
if /i 1%yy% lss 20 set "yy=0%yy%"
if /i %yy% lss 80 (set yy=20%yy%) else (if %yy% lss 100 set yy=19%yy%)
if defined p1 EndLocal&call set "%~1=%mm%-%dd%-%yy%"&exit /b %yy%%mm%%dd%
EndLocal&echo.%mm%-%dd%-%yy%&exit /b %yy%%mm%%dd%

:s_fixdate
if /i "%1:~0,1%" gtr "9" shift
for /f "skip=1 tokens=2-4 delims=(-)" %%e in ('date^<nul') do (
set %%e=%1&set %%f=%2&set %%g=%3
)
exit /b

I have some other groovy command line and script friendly date and date math routines if anyone is interested.

carlsomoQuote from: Salmon Trout on June 03, 2011, 05:02:54 PM
OK, but why don't you address the issue of differing local date formats?

he said format is not a problem, read first postQuote from: a117yogi on June 04, 2011, 08:48:55 PM
he said format is not a problem, read first post

I'm talking about your "solution" which does not work for every local date format.Here is the updated solution to get the current date set in mm-dd-yyyy
This is a batch file that does not have to read the registry
if you pass a variable name as argument it gets set to the date in mm-dd-yyyy
errorlevel is set to yyyymmdd

It can now handle the 05-Jun-11 format with minor modifications to what i posted prior.

Code: [Select]@echo off&SetLocal EnableDelayedExpansion&goto :start
:GetDate [EnVar]
echo.GetDate [EnVar] Sets date into environment variable, EnVar as: mm-dd-yyyy
echo.Usage: GetDate mdy^&set ymd=%%errorlevel%%, ^(use %% rather than ^^! in command line)
echo.Usage: GetDate mdy^&set ymd=^^!errorlevel^^!, ^(use ^^! rather than %% in script^)
echo.If no argument passed it echo's the date in mm-dd-yyyy format
echo.Returns yyyymmdd in errorlevel regardless if Envar is passed as argument or not
echo.Works on NT/2K/XP/Vista/Win7 machines independent of most regional date settings
EndLocal&exit /b
:start
set p1=%~1&if /i !p1! equ /? goto :GetDate
for /f "tokens=1-4 delims=/-. " %%a in ("%date%") do call :s_fixdate %%a %%b %%c %%d
if /i 1%yy% lss 20 set "yy=0%yy%"
if /i %yy% lss 80 (set yy=20%yy%) else (if %yy% lss 100 set yy=19%yy%)
if defined p1 EndLocal&call set "%~1=%mm%-%dd%-%yy%"&exit /b %yy%%mm%%dd%
EndLocal&echo.%mm%-%dd%-%yy%&exit /b %yy%%mm%%dd%

:s_fixdate
if /i "%1:~0,1%" gtr "9" shift
for /f "skip=1 tokens=2-4 delims=(-)" %%e in ('date^<nul') do (
set %%e=%1&set %%f=%2&set %%g=%3
)
if /i "%mm:~0,1%" gtr "9" call :month_convert mm
exit /b

:month_convert
SetLocal
set "months=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
call set "month=%%%~1%%"
for /l %%a in (1,1,12) do (
set/a mon=%%a
call :month_assign !mon!
if /i !errorlevel! equ 0 (
if /i 1!mon! lss 20 set "mon=0!mon!"
goto :out
)
)
:out
EndLocal&call set "%~1=%mon%"&exit /b

:month_assign mnum
set/a mnum=%~1
for /f "tokens=%mnum%" %%m in ("%months%") do if /i %month% equ %%m exit /b 0
exit /b 1
Quote
@echo off&SetLocal EnableDelayedExpansion&goto :start
:GetDate [EnVar]
echo.GetDate [EnVar] Sets date into environment variable, EnVar as: mm-dd-yyyy
echo.Usage: GetDate mdy^&set ymd=%%errorlevel%%, ^(use %% rather than ^^! in command line)
echo.Usage: GetDate mdy^&set ymd=^^!errorlevel^^!, ^(use ^^! rather than %% in script^)
echo.If no argument passed it echo's the date in mm-dd-yyyy format
echo.Returns yyyymmdd in errorlevel regardless if Envar is passed as argument or not
echo.Works on NT/2K/XP/Vista/Win7 machines independent of most regional date settings
EndLocal&exit /b
:start
set p1=%~1&if /i !p1! equ /? goto :GetDate
for /f "tokens=1-4 delims=/-. " %%a in ("%date%") do call :s_fixdate %%a %%b %%c %%d
if /i 1%yy% lss 20 set "yy=0%yy%"
if /i %yy% lss 80 (set yy=20%yy%) else (if %yy% lss 100 set yy=19%yy%)
if defined p1 EndLocal&call set "%~1=%mm%-%dd%-%yy%"&exit /b %yy%%mm%%dd%
EndLocal&echo.%mm%-%dd%-%yy%&exit /b %yy%%mm%%dd%

:s_fixdate
if /i "%1:~0,1%" gtr "9" shift
for /f "skip=1 tokens=2-4 delims=(-)" %%e in ('date^<nul') do (
set %%e=%1&set %%f=%2&set %%g=%3
)
if /i "%mm:~0,1%" gtr "9" call :month_convert mm
exit /b

:month_convert
SetLocal
set "months=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
call set "month=%%%~1%%"
for /l %%a in (1,1,12) do (
set/a mon=%%a
call :month_assign !mon!
if /i !errorlevel! equ 0 (
if /i 1!mon! lss 20 set "mon=0!mon!"
goto :out
)
)
:out
EndLocal&call set "%~1=%mon%"&exit /b

:month_assign mnum
set/a mnum=%~1
for /f "tokens=%mnum%" %%m in ("%months%") do if /i %month% equ %%m exit /b 0
exit /b 1

Zowie! There is enough code here to launch a space shuttle.

I was able to clean up the code and run it, but I'm unsure of my results or what to do with them. The code set an environmental variable with todays date (mm-dd-yyyy). With all due respect, can't this be done by parsing the %date% variable?

Quote
This getdate batch comes in handy to determine the date fields without having to read the registry:

Why not use the registry? The registry serves as a database for all the system settings, so why not go the source for this information?

The founder of KISS University must be spinning in his grave. Quote from: Sidewinder on June 06, 2011, 08:18:02 AM
Why not use the registry? The registry serves as a database for all the system settings, so why not go the source for this information?

You mean like this?

Code: [Select]for /f "skip=2 tokens=3 delims= " %%A in ('reg query "HKEY_USERS\.DEFAULT\Control Panel\International" /v sShortDate') do echo %%A
Quote
The founder of KISS University must be spinning in his grave.

But his alumni are still around...

I was at the Advanced Studies School of that University, but I never abbreviate it.

The above line returns this here in the UK:

Code: [Select]dd/MM/yyyy
Lots of other goodies... sCurrency, sLanguage, sTimeFormat, etcthe registry related satement:
Code: [Select]for /f "skip=2 tokens=3 delims= " %%A in ('reg query "HKEY_USERS\.DEFAULT\Control Panel\International" /v sShortDate') do echo %%A
certainly gives you M/d/yyyy or whatever format but let's say you wish to create 'yyyymmdd.filename.jpg'
one still has to assign date variables once the format is known. Thus there is more code work to do.

In the end I can put this in a script:
Code: [Select]call getdate today_mdy&set today_ymd=!errorlevel!
ren "filename.ext" "%today_ymd%.filename.ext"
echo "filename.ext" was renamed to" %today_ymd%.filename.ext" on %today_mdy%>>file_rename.log

this statement:
Code: [Select]for /f "skip=1 tokens=2-4 delims=(-)" %%e in ('date^<nul') do set %%e=%1&set %%f=%2&set %%g=%3
where %1 thru %4 came from parsing %date% in whatever format the user has on their machine
makes the assignments in all of the formats, excluding "Mon 06/06/2011" (and/11) and "06-Jun-2011"
ie. mm=06 dd=06 and yy=2011 (or 11) regardless of MM/dd/yyyy, yy/MM/dd, or yyyy/MM/dd
The 'shift' containing statement strips "Mon 06/06/2011" to "06/06/2011" in the M/d/yyyy and M/d/yy formats prior to the for loop. The 'if' statement following and the called code below it is necessary to change 'Jun' to '06' (and not '6')

Since I am an admin I don't have a problem accessing the registry but limitted users may not in all cases.
I was aware of the registry keys holding the date format but I decided to avoid it and I don't think that lengthened the overall code by much and the desired result pops out in less than a second (0.24 on my machine).

I posted here because I had already written the batch code (that I use all the time) and I wished to help the fellow who made the original post. Then Salmon rightly pointed out the "06-Jun-2011" format wasn't covered so I covered it for completeness sake.

Now I can run date related batch code on mutliple machines with differing operating systems and obtain the date (in the formats I use) without worrying about the regional setting or user preference on any given machine.

Now it's my turn.... Please shorten the routine using registry keys or whatever to return the date in two USEFUL formats. My goal at the outset was not to write the shortest code possible but to get the job done as I have had routines blow up when running into differing formats everywhere I go.

Respectfully, CarlAn alternative to using sShortdate would be using iDate and sDate in the HKCU\Control Panel\International registry key. The iDate defines three values and three date formats (0=mm/dd/yy, 1=dd/mm/yy, and 2=yy/mm/dd). The sDate value defines the separator which can be used as the delimeter in a for statement.

The only roadblock is that some machines display the day of week with the date command. This can be determined by using a regular expression in the findstr command.

Code: [Select]for /f "skip=2 tokens=3" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\International" /v iDate') do (
set idate=%%a
)

for /f "skip=2 tokens=3" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\International" /v sDate') do (
set sdate=%%a
)

:: If first CHARACTER of date is alpha, presume DOW
::
echo %date:~0,1% | findstr /r "[A-Z]" > nul

if errorlevel 1 (
for /f "tokens=1-3* delims=%sdate% " %%a in ('date /t') do (
if %idate%==0 (set year=%%c & set month=%%a & set day=%%b)
if %idate%==1 (set year=%%c & set month=%%b & set day=%%a)
if %idate%==2 (set year=%%a & set month=%%b & set day=%%c)
)
) else (
for /f "tokens=1-4* delims=%sdate% " %%a in ('date /t') do (
if %idate%==0 (set year=%%d & set month=%%b & set day=%%c)
if %idate%==1 (set year=%%d & set month=%%c & set day=%%b)
if %idate%==2 (set year=%%b & set month=%%c & set day=%%d)
)
)

Once the date components (month, day, year) are isolated, it should be childs play to format them any which way.

Just a thought. VBScript hybrid...

Code: [Select]@echo off
echo Wscript.echo eval(WScript.Arguments(0))>evaluate.vbs
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "FormatDateTime(Now, 0)"') do echo FormatDateTime(Now, 0) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "FormatDateTime(Now, 1)"') do echo FormatDateTime(Now, 1) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "FormatDateTime(Now, 2)"') do echo FormatDateTime(Now, 2) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "FormatDateTime(Now, 3)"') do echo FormatDateTime(Now, 3) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "FormatDateTime(Now, 4)"') do echo FormatDateTime(Now, 4) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "Year (Date)"') do echo Year(Date) %%A
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "Month(Date)"') do if %%A lss 10 (
echo Month^(Date^) 0%%A
) else (
echo Month^(Date^) %%A
)
for /f "delims=" %%A in ('cscript //nologo evaluate.vbs "Day (Date)"') do if %%A lss 10 (
echo Day^(Date^) 0%%A
) else (
echo Day^(Date^) %%A
)
Code: [Select]FormatDateTime(Now, 0) 07/06/2011 08:20:15 PM
FormatDateTime(Now, 1) 07 June 2011
FormatDateTime(Now, 2) 07/06/2011
FormatDateTime(Now, 3) 08:20:16 PM
FormatDateTime(Now, 4) 20:20
Year(Date) 2011
Month(Date) 06
Day(Date) 07Thank you for the informative response. I've noticed that you give a lot of your time to help share your knowledge and respond to querries and conundrums. I wish more people had that attitude.


Discussion

No Comment Found