Logo Questions Linux Laravel Mysql Ubuntu Git Menu

Setting a windows batch file variable to the day of the week

I have a windows batch file that runs daily. Wish to log data into a file and want to rotate it (i.e. having at most the last 7 days worth of data).

Looked into the commands DATE and DELIMS - Cannot figure out a solution.

Is there a simple solution to create a file name that contains the day of the week i.e. 0 for monday etc.

Or do I have to resort to some better shell script.

like image 754
Ed Heal Avatar asked Jul 06 '12 14:07

Ed Heal

People also ask

What does 0 |% 0 Do in batch?

What it is: %0|%0 is a fork bomb. It will spawn another process using a pipe | which runs a copy of the same program asynchronously. This hogs the CPU and memory, slowing down the system to a near-halt (or even crash the system).

What is @echo in batch file?

To display the command prompt again, type echo on. To prevent all commands in a batch file (including the echo off command) from displaying on the screen, on the first line of the batch file type: @echo off. You can use the echo command as part of an if statement.

3 Answers

%DATE% is not your friend. Because the %DATE% environment variable (and the DATE command) returns the current date using the Windows short date format that is fully and endlessly customizable. One user may configure the system to return 07/06/2012 while another might choose Fri060712. Using %DATE% is a complete nightmare for a BAT programmer.

There are two possible approaches to solve this problem:

  1. You may be tempted to temporarily change the short date format, by changing the locale settings in the registry value HKCU\Control Panel\International\sShortDate, to your recognizable format. Then access %DATE% to get the date in the format you want; and finally restore the format back to the original user format. Something like this

    reg copy "HKCU\Control Panel\International" "HKCU\Control Panel\International-Temp" /f >nul reg add "HKCU\Control Panel\International" /v sShortDate /d "ddd" /f >nul set DOW=%DATE% reg copy "HKCU\Control Panel\International-Temp" "HKCU\Control Panel\International" /f >nul 

    but this method has two problems:

    • it tampers with a global registry value for its local particular purpouses, so it may interfere with other processes or user tasks that at the very same time query the date in short date format, including itself if run simultaneously.

    • and it returns the three letter day of the week in the local language that may be different in different systems or different users.

  2. use WMIC Win32_LocalTime, that returns the date in a convenient way to directly parse it with a FOR command.

    FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (   set DOW=%%A ) 

    this is the method I recommend.

like image 151
PA. Avatar answered Sep 18 '22 22:09


few more ways:

1.Robocopy not available in XP but can be downloaded form with win 2003 resource tool kit .Also might depend on localization:

@echo off setlocal  for /f "skip=8 tokens=2,3,4,5,6,7,8 delims=: " %%D in ('robocopy /l * \ \ /ns /nc /ndl /nfl /np /njh /XF * /XD *') do (  set "dow=%%D"  set "month=%%E"  set "day=%%F"  set "HH=%%G"  set "MM=%%H"  set "SS=%%I"  set "year=%%J" )  echo Day of the week: %dow% endlocal 

2.MAKECAB - works on every windows machine (but creates a small temp file).Function provided by carlos:

@Echo Off   Call :GetDate.Init Rem :GetDate.Init should be called one time in the code before call to :Getdate Call :GetDate Echo weekday:%weekday%  Goto :EOF  :GetDate.Init Set /A "jan=1,feb=2,mar=3,apr=4,may=5,jun=6,jul=7,aug=8,sep=9,oct=10,nov=11,dec=12" Set /A "mon=1,tue=2,wed=3,thu=4,fri=5,sat=6,sun=7" ( Echo .Set InfHeader="" Echo .Set InfSectionOrder="" Echo .Set InfFooter="%%2" Echo .Set InfFooter1="" Echo .Set InfFooter2="" Echo .Set InfFooter3="" Echo .Set InfFooter4="" Echo .Set Cabinet="OFF" Echo .Set Compress="OFF" Echo .Set DoNotCopyFiles="ON" Echo .Set RptFileName="NUL" ) >"%Temp%\~foo.ddf" Goto :Eof  :GetDate Set "tf=%Temp%\~%random%" Makecab /D InfFileName="%tf%" /F "%Temp%\~foo.ddf" >NUL For /F "usebackq tokens=1-7 delims=: " %%a In ("%tf%") Do ( Set /A "year=%%g,month=%%b,day=1%%c-100,weekday=%%a" Set /A "hour=1%%d-100,minute=1%%e-100,second=1%%f-100") Del "%tf%" >NUL 2>&1 Goto :Eof 

3.W32TM - uses command switches introduced in Vista so will not work on windows 2003/XP:

@echo off setlocal call :w32dow day_ow echo %day_ow% pause exit /b 0 endlocal :w32dow [RrnVar] setlocal  rem :: prints the day of the week rem :: works on Vista and above   rem :: getting ansi date ( days passed from 1st jan 1601 ) , timer server hour and current hour FOR /F "tokens=4,5 delims=:( " %%D in ('w32tm /stripchart /computer:localhost  /samples:1  /period:1 /dataonly /packetinfo^|find "Transmit Timestamp:" ') do (  set "ANSI_DATE=%%D"  set  "TIMESERVER_HOURS=%%E" )  set  "LOCAL_HOURS=%TIME:~0,2%" if "%TIMESERVER_HOURS:~0,1%0" EQU "00" set TIMESERVER_HOURS=%TIMESERVER_HOURS:~1,1% if "%LOCAL_HOURS:~0,1%0" EQU "00" set LOCAL_HOURS=%LOCAL_HOURS:~1,1% set /a OFFSET=TIMESERVER_HOURS-LOCAL_HOURS  rem :: day of the week will be the modulus of 7 of local ansi date +1 rem :: we need need +1 because Monday will be calculated as 0 rem ::  1st jan 1601 was Monday  rem :: if abs(offset)>12 we are in different days with the time server  IF %OFFSET%0 GTR 120 set /a DOW=(ANSI_DATE+1)%%7+1 IF %OFFSET%0 LSS -120 set /a DOW=(ANSI_DATE-1)%%7+1 IF %OFFSET%0 LEQ 120 IF %OFFSET%0 GEQ -120 set /a DOW=ANSI_DATE%%7+1   rem echo Day of the week: %DOW%  endlocal & if "%~1" neq "" (set "%~1=%DOW%") else echo %DOW% 

4..bat/jscript hybrid (must be saved as .bat):

 @if (@x)==(@y) @end /***** jscript comment ******  @echo off  for /f  %%d in ('cscript //E:JScript //nologo "%~f0"') do echo %%d  exit /b 0  *****  end comment *********/  WScript.Echo((new Date).getDay()); 

5..bat/vbscript hybrid (must be saved as .bat)

 :sub echo(str) :end sub echo off '>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul  '& echo/  '& for /f %%w in ('cscript /nologo /E:vbscript %~dpfn0') do echo day of the week %%w '& echo/ '& del /q "'.exe" >nul 2>&1 '& exit /b  WScript.Echo Weekday(Date) WScript.Quit 

6.powershell can be downloaded from microsoft.Available by default in everything form win7 and above:

@echo off setlocal for /f %%d in ('"powershell (Get-Date).DayOfWeek.Value__"') do set dow=%%d  echo day of the week : %dow% endlocal 

7.WMIC already used as an answer but just want to have a full reference.And with cleared <CR>:

@echo off setlocal for /f "delims=" %%a in ('wmic path win32_localtime get dayofweek /format:list ') do for /f "delims=" %%d in ("%%a") do set %%d  echo day of the week : %dayofweek% endlocal 

9.Selfcompiled jscript.net (must be saved as .bat):

@if (@X)==(@Y) @end /****** silent line that start jscript comment ******  @echo off :::::::::::::::::::::::::::::::::::: :::       compile the script    :::: :::::::::::::::::::::::::::::::::::: setlocal if exist "%~n0.exe" goto :skip_compilation  set "frm=%SystemRoot%\Microsoft.NET\Framework\" :: searching the latest installed .net framework for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (     if exist "%%v\jsc.exe" (         rem :: the javascript.net compiler         set "jsc=%%~dpsnfxv\jsc.exe"         goto :break_loop     ) ) echo jsc.exe not found && exit /b 0 :break_loop   call %jsc% /nologo /out:"%~n0.exe" "%~dpsfnx0" :::::::::::::::::::::::::::::::::::: :::       end of compilation    :::: :::::::::::::::::::::::::::::::::::: :skip_compilation  "%~n0.exe"  exit /b 0   ****** end of jscript comment ******/ import System; import System.IO;  var dt=DateTime.Now;  Console.WriteLine(dt.DayOfWeek); 
like image 37
npocmaka Avatar answered Sep 20 '22 22:09


FOR /F "TOKENS=1-3 DELIMS=/" %%A IN ("%DATE%") DO SET /A MM=10%%A %% 100, DD=10%%B %% 100, YY=%%C
IF %MM% LSS 3 SET /A MM+=12, YY-=1
SET /A A=YY/100, B=A/4, C=2-A+B, E=36525*(YY+4716)/100, F=306*(MM+1)/10, JDN=C+DD+E+F-1524
SET /A DOW=(JDN+1)%%7

DOW is 0 for Sunday, 1 for Monday, etc.

like image 34
Aacini Avatar answered Sep 18 '22 22:09