Bit of a weird one. I've been messing around with windows batch and time comparisons to schedule a task. Now I know there's a million better ways to do it, but our work machines are pretty locked down, so a batch script seems like the easiest way to actually achieve what I needed without some crazy workaround. I'm also well aware that the idea behind this is pretty gross. I'm not looking for perfection here, I'm just looking for it to work.
Basically at 17:00 on the 23rd November, I needed to move a file from one place to another. Problem is that I wouldn't actually be physically present at that time due to some other commitments, so I figured a batch script that was stuck in a loop of nothing until a certain date/time would work. So I cobbled together the following quickly the night before:
:dateloop
if %date% LSS 23/11/2019 goto dateloop
:timeloop
if %time% LSS 17:00 goto timeloop
<xcopy operation goes here>
And ran it overnight. So imagine my surprise when I came to my machine the next morning to check my emails and noticed that the file had been moved. Thankfully I was able to revert the file and rescheduled my day to do it manually.
I ran some tests last night, making sure that the script didn't exit upon completion so I could read the echo output. And it turns out that it was all running fine until 2:00, when the script decided "yes, this is after 17:00".
I could test it again tonight, and I do plan to, with the time format written out the long way (17:00:00:00) but I was wondering if anyone could confirm before I do, as that's a good while away, if this is the cause of my problem?
If you type IF /? at the command prompt, the help text will include this:
If Command Extensions are enabled IF changes as follows:
IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command
where compare-op may be one of:
EQU - equal
NEQ - not equal
LSS - less than
LEQ - less than or equal
GTR - greater than
GEQ - greater than or equal
and the /I switch, if specified, says to do case insensitive string
compares. The /I switch can also be used on the string1==string2 form
of IF. These comparisons are generic, in that if both string1 and
string2 are both comprised of all numeric digits, then the strings are
converted to numbers and a numeric comparison is performed.
As you can see, comparison is on strings unless the strings to compare contain only numeric digits. As time contains the non-numeric characters ":" and ".", the time is treated as a string, and of course "2" comes after the "1" from "17:00".
However, with the command echo [%time%] you'll notice that if the time is less than 10, it adds a space at the front. Therefore, you can get correct results with a string comparison as long as you take the space into account. So replace your problematic statement with the following one:
if "%time%" LSS "17:00" goto timeloop
That should fix it.
If compares strings alphabetically or numbers.
You need to rework your code and compare times as numbers. So you also need a reliable way to get date parts as numbers - date and time variables are not suitable because they can be in different formats depending on your settings.
Try this instead:
#echo off
::GOTO comment macro
set "[:=goto :]%%"
::brackets comment macros
set "[=rem/||(" & set "]=)"
for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do #for /f %%# in ("%%#") do #set %%#
%[:%
echo %day%
echo %DayOfWeek%
echo %hour%
echo %minute%
echo %month%
echo %quarter%
echo %second%
echo %weekinmonth%
echo %year%
%:]%
:dateloop
if %year%%month%%day% LSS 20191132 goto dateloop
:timeloop
if %hour%%minute% LSS 1700 goto :timeloop
D:\> set "today=%date:~10,4%-%date:~7,2%-%date:~4,2%"
D:\> mkdir SVN_BACKUP_DUMP_TEST\%today%
D:\> CD SVN_BACKUP_DUMP_TEST\%today%
when we are make bat file this command not work
Format of date of referenced environment variable DATE depends on region setting, i.e. which country and derived from country which date format is configured for the current account. So which string is assigned to environment variable today and if that string is valid for a directory or file name depends on account specific date format.
On my computer with German set as country for my account output of echo %DATE% is 13.11.2017. So the date format is dd.MM.yyyy with point as separator, no weekday and always two digits for date and month even for a date or month less than 10.
The command line
echo %DATE:~10,4%-%DATE:~7,2%-%DATE:~4,2%
produces on my machine with my account and my region settings the output:
-01-1.
That is definitely not the current date in format yyyy-MM-dd.
The solution is using following batch code:
#echo off
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "Today=%%I"
set "Today=%Today:~0,4%-%Today:~4,2%-%Today:~6,2%"
mkdir "SVN_BACKUP_DUMP_TEST\%Today%" 2>nul
cd "SVN_BACKUP_DUMP_TEST\%Today%"
This is a region independent solution. The batch code is completely explained in answer on
Why does %date% produce a different result in batch file executed as scheduled task?
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean? is one more question on which answer should be read to understand the string substitutions. And run in a command prompt window set /? to get displayed the help for command SET explaining string substitution, too.
I don't know much about windows .bat file syntax. My simple requirement is to create a folder at a specific location with name as current date. I tried searching this on google but didn't get any good option. Is there any way to do this?
mkdir %date:~-4,4%%date:~-10,2%%date:~7,2%
Quick and dirty: If you can live with the date being UTC instead of local, you can use:
for /f "skip=1" %%d in ('wmic os get localdatetime') do if not defined mydate set mydate=%%d
md %mydate:~0,8%
Works in all locales. Only on XP and higher, though.
Try this (an equivalent of bash backquotes):
for /f "tokens=1* delims=" %%a in ('date /T') do set datestr=%%a
mkdir %datestr%
For further information, see http://ss64.com/nt/for_cmd.html
You need to get rid of the '/' characters in the date before you can use it in mkdir like this:
setlocal enableextensions
set name=%DATE:/=_%
mkdir %name%
If you want mm-dd-yyyy format you can use:
mkdir %date:~-10,2%"-"%date:~7,2%"-"%date:~-4,4%
This depends on the regional settings of the computer, so first check the output of the date using the command prompt or by doing an echo of date.
To do so, create a batch file and add the below content
echo %date%
pause
It produces an output, in my case it shows Fri 05/06/2015.
Now we need to get rid of the slash (/)
For that include the below code in the batch file.
set temp=%DATE:/=%
if you echo the "temp", you can see the date without the slash in it.
Now all you need to do is formatting the date in the way you want.
For example I need the date in the format of YYYYMMDD, then I need to set the dirname as below
To explain how this works, we need to compare the value of temp
Fri 05062015.
now position each characters with numbers starting with 0.
Fri 0506201 5
01234567891011
So for the date format which I need is 20150605,
The Year 2015, in which 2 is in the 8th position, so from 8th position till 4 places, it will make 2015.
The month 06, in which 0 is in the 6th position, so from 6th position till 2 places, it will make 06.
The day 05, in which 0 is in the 4th position, so from 4th position till 2 places, it will make 05.
So finally to set up the final format, we have the below.
SET dirname="%temp:~8,4%%temp:~6,2%%temp:~4,2%"
To enhance this date format with "-" or "_" in between the date, month and year , you can modify with below
SET dirname="%temp:~8,4%-%temp:~6,2%-%temp:~4,2%"
or
SET dirname="%temp:~8,4%_%temp:~6,2%_%temp:~4,2%"
So the final batch code will be
======================================================
#echo off
set temp=%DATE:/=%
set dirname="%temp:~8,4%%temp:~6,2%%temp:~4,2%"
mkdir %dirname%
======================================================
The directory will be created at the place where this batch executes.
echo var D = new Date() > tmp.js
echo D = (D.getFullYear()*100+D.getMonth()+1)*100+D.getDate() >> tmp.js
echo WScript.Echo( 'set YYYYMMDD='+D ) >> tmp.js
echo #echo off > tmp.bat
cscript //nologo tmp.js >> tmp.bat
call tmp.bat
mkdir %YYYYMMDD%
I had a problem with this because my server ABSOLUTELY had to have its date in MM/dd/yyyy format, while I wanted the directory to be in YYYY-MM-DD format for neatness sake. Here's how to get it in YYYY-MM-DD format, no matter what your regional settings are set as.
Find out what gets displayed when you use %DATE%:
From a command prompt type:
ECHO %DATE%
Mine came out 03/06/2013 (as in 6th March 2013)
Therefore, to get a directory name as 2013-03-06, code this into your batch file:
SET dirname="%date:~6,4%-%date:~0,2%-%date:~3,2%"
mkdir %dirname%
for /F “tokens=1-4 delims=/ ” %%A in (‘date /t’) do (
set DateDay=%%A
set DateMonth=%%B
set DateYear=%%C
)
set CurrentDate=%DateDay%-%DateMonth%-%DateYear%
md %CurrentDate%
This will give you a newly created folder with today’s date, in the format of DD-MM-YY
Sourced from: Ali's Knowledge Base
This should work:
mkdir %date%
If it doesn't, try this:
setlocal enableextensions
mkdir %date%
this is a more simpler solution.
#ECHO OFF
set name=%date%
echo %name%
mkdir %name%
I am sitting in exactly the same boat as you as soon as i am AM before 10 i cannot use the below, i have set my time from 12hr to 24 hr, changed hh/mm to HH/mm I have tried most of the codes i could find. below will help at least a little. tweak and fix :)
Below may help also
set DD=%DATE:~0,2%
set MM=%DATE:~3,2%
set YY=%DATE:~8,2%
set YYYY=%DATE:~6,4%
set hh=%hh: =0%
set mm=%TIME:~3,2%
if "%time:~0,1%" == " " (set folderdate=0%time:~1,1%) ELSE set folderdate=%time:~0,2%
mkdir folderdate=%date:~6%%date:~3,2%%date:~0,2%_%folderdate%%time:~3,2%
copy \Makereport*.CSV \Makereport\%folderdate%\
cd %folderdate%
REM -( 7zip in c:\batch)
Path = c:\batch
7z a Retail.zip *.CSV -pRetailPassword
cd..
del *.csv
the expression %date:~p,n% returns n number of characters from position p in the date string.
if my system date string is Mon23/11/2015
the command
%date:~1,3%
returns the value
Mon
the command
%date:~10,4%
returns the value
2015
and in conjunction with the md (or mkdir) command
the command
md %date:~10,4%%date:~7,2%%date:~4,2%
makes a directory named
20151123
likewise if your date string in in the format
Monday, 23/Nov/2015
the command
md %date:~16,4%%date:~12,3%%date:~9,2%
makes a directory named
2015Nov23
If you accidentally return characters from the date string that are not allowed in folder names or use invalid values for p and n you will get an error.
Additionally if you return values that include \ this may create a folder within a folder.
If your locale has date format "DDMMYYYY" you'll have to set it this way:
set datestr=%date:~-4,4%%date:~3,2%%date:~-10,2%
mkdir %datestr%
This works for me, try:
ECHO %DATE:~7,2%_%DATE:~4,2%_%DATE:~12,2%
Thanks for the info all, very helpful. I needed something that could create "backup" folder as often as every minute in the same directory, as well as call on it later in the script. Here's what I came up with:
# echo off
CD %userprofile%\desktop
SET Datefolder="%DATE:~4,2%-%DATE:~7,2%-%DATE:~12,2%_%time:~1,1%%time:~3,2%"
MD "%Datefolder%"
This gives me a folder on the currently logged on user's desktop named: mm-dd-yy_hmm (hour minute minute) ie: 07-28-15_719
You'll like this, change it so that it can suit your requirements.
mkdir today
Copy Desktop\test1\*.* today
setlocal enableextensions
set name=%DATE:/=_%
Rename "today" _OlddatabaseBackup_"%name%"
Use this batch script made by me:
#echo off
title Folder Creator
color b
setlocal enabledelayedexpansion
echo Enter the folder name, you can use these codes:
echo /t - Time (eg. 16:29)
echo /d - Date (eg. 17-02-19)
echo /a - Day (eg. 17)
echo /m - Month (eg. 02)
echo /y - Year (eg. 19)
echo /f - Full Year (eg. 2019)
echo.
set /p foldername=Folder Name:
set foldername=%foldername:/t=!time:~0,5!%
set foldername=%foldername:/d=!date:~0,2!-!date:~3,2!-!date:~8,2!%
set foldername=%foldername:/a=!date:~0,2!%
set foldername=%foldername:/m=!date:~3,2!%
set foldername=%foldername:/y=!date:~8,2!%
set foldername=%foldername:/f=!date:~6,4!%
md %foldername%
For example if you wanted to make a folder named the date in the DD-MM-YY format you would type "/d" but if you wanted to do that in the DD-MM-YYYY format you would type "/a-/m-/f".
I use the next code to make a file copy (e.g. test.txt) before replacing:
cd /d %~dp0
set backupDir=%date:~7,2%-%date:~-10,2%-%date:~-2,2%_%time:~0,2%.%time:~3,2%.%time:~6,2%
echo make dir %backupDir% ...
md "%backupDir%"
copy test.txt %backupDir%
It creates directory in format DD-MM-YY_HH.MM.SS and places text.txt there.
Time with seconds in the name is necessary to create directory without additional verification.
https://stackoverflow.com/a/31789045/1010918 foxidrive's answer helped me get the folder with the date and time I wanted. I would like to share this method here since it worked great for me and I think it could help other people too, regardless of their locale.
rem The four lines below will give you reliable YY DD MM YYYY HH Min Sec MS variables in XP Pro and higher.
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
set "dirname=%YYYY%-%MM%-%DD% %HH%-%Min%-%Sec%"
:: remove echo here if you like
echo "dirName"="%dirName%"
this worked better for me,
#echo off
set temp=%DATE:/=%
set dirname="%temp:~4,4%%temp:~2,2%%temp:~0,2%"
mkdir %dirname%
For YYYY.MM.DD format with HUN settings use following. It converts "2021. 02. 23." to "2021.02.23":
SET dirname="%date:~0,5%%date:~6,3%%date:~10,2%"
md %dirname%
G:
cd G:/app/
mkdir %date:~7,2%%date:~-10,2%%date:~-4,4%
cd %date:~7,2%%date:~-10,2%%date:~-4,4%
sqlplus sys/sys as sysdba #c:/new
I needed both the date and time and used:
mkdir %date%-%time:~0,2%.%time:~3,2%.%time:~6,2%
Which created a folder that looked like:
2018-10-23-17.18.34
The time had to be concatenated because it contained : which is not allowed on Windows.
setlocal enableextensions
set name="%DATE:/=_%"
mkdir %name%
to create only one folder like "Tue 01_28_2020"
I am need to log systems that do not have a specific file in a specific folder and have created the below batch which works fine. It will be called by the domain logon script (Clients are Windows XP in a 2003 AD domain):
IF EXIST "C:\Documents and Settings\%username%\Application Data\Microsoft\Outlook\test.OTM" (
goto END
) ELSE (
echo %DATE%_%TIME%_%COMPUTERNAME% >> %LOG1%
)
In addition to this, however, if the file is present I need to check that it has a specific modified date and if not then output it to a log file. So far I am stumped and would greatly appreciate any feedback/help on this. Thanks.
You can obtain information about the file's modification date and time in a batch script, but you'll need to remember these things:
it comes as a combination of date and time;
it's locale specific;
it's a string.
That means that before comparing you'll need to cut off the time part, for which you'll need to take into account the display format as specified in the system's regional settings. And because it's a string, you'll probably be only able to check whether it is a specific date, but not whether it belongs to a specific period.
And here's how you can have it implemented:
SET filename="C:\Documents and Settings\%username%\Application Data\Microsoft\Outlook\test.OTM"
IF NOT EXIST %filename% GOTO log
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
IF "%filedatetime:~0,-6%" == "%checkdate%" GOTO END
:log
ECHO %DATE%_%TIME%_%COMPUTERNAME% >> %LOG1%
On my system %%~tf would return the date and time formatted as dd.MM.yyyy hh:mm. So the %filedatetime:~0,-6% part follows that format and cuts off the time part accordingly. You may need to change the expression slightly to fit your case.
One last thing is, there's a predefined variable called USERPROFILE. It points to the active user's 'home' folder, C:\Documents and Settings\username. So you can reduce the path string to this: "%USERPROFILE%\Application Data\Microsoft\Outlook\test.OTM".
If the date is relative to today (e.g. file updated within the last 7 days) you can use the "forfiles" command which has date calculations built in.
For example: to list all files that have been modified in the last 2 days:
forfiles /D -2 /C "cmd /c ECHO file selected...#path, dated #fdate"