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

后端 未结 17 1892
南方客
南方客 2020-11-27 20:14

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

相关标签:
17条回答
  • 2020-11-27 20:39

    I thought that my first answer gives the correct day of week as a number between 0 and 6. However, because you had not indicated why this answer does not give the result you want, I can only guess the reason.

    The Batch file below create a log file each day with a digit in the name, 0=Sunday, 1=Monday, etc... The program assume that echo %date% show the date in MM/DD/YYYY format; if this is not the case, just change the position of mm and dd variables in the for command.

    @echo off
    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, dow=(c+dd+e+f-1523)%%7
    echo Today log data > Day-%dow%.txt
    

    If this is not what you want, please indicate the problem so I can fix it.

    EDIT: The version below get date parts independent of locale settings:

    @echo off
    for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
       for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
          set %%A=%%a
          set %%B=%%b
          set %%C=%%c
       )
    )
    set /A mm=10%mm% %% 100, dd=10%dd% %% 100
    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, 
    
    dow=(c+dd+e+f-1523)%%7
    echo Today log data > Day-%dow%.txt
    

    EDIT: The version below insert day of week as 3-letter short name:

    @echo off
    for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
       for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
          set %%A=%%a
          set %%B=%%b
          set %%C=%%c
       )
    )
    set /A mm=10%mm% %% 100, dd=10%dd% %% 100
    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, 
    
    dow=(c+dd+e+f-1523)%%7 + 1
    for /F "tokens=%dow%" %%a in ("Sun Mon Tue Wed Thu Fri Sat") do set dow=%%a
    echo Today log data > Day-%dow%.txt
    

    Regards,

    Antonio

    0 讨论(0)
  • 2020-11-27 20:39

    First - Copy CON SETUPDAY.001 SET WORKDAY=^Z (very important - no cr/lf)

    DATE /T >SETUPDAY.002
    COPY SETUPDAY.001+SETUPDAY.002 NEWDAY.BAT >nul
    CALL NEWDAY.BAT
    
    SET WEEKDAY=%WORKDAY:~0,3%
    SET MDY=%WORKDAY:~4,10%
    

    USE %WEEKDAY% IN YOUR SCRIPT

    0 讨论(0)
  • 2020-11-27 20:39

    I Improved Aacini Answer to make it Echo Full day of week Name

    So here's my Code

    @echo off
    for /F "skip=1 tokens=2-4 delims=(-/)" %%A in ('date ^< NUL') do (
       for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
          set %%A=%%a
          set %%B=%%b
          set %%C=%%c
       )
    )
    set /A mm=10%mm% %% 100, dd=10%dd% %% 100
    if %mm% lss 3 set /A mm+=12, yy-=1
    set /A a=yy/100, b=a/4, c=4-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10,dow=(c+dd+e+f-1523)%%7 + 1
    for /F "tokens=%dow%" %%a in ("Sunday Monday Tuesday Wednesday Thursday Friday Saturday ") do set dow=%%a
    echo Today is %dow%>"Today is %dow%.txt"
    echo Today is %dow%
    Pause>Nul
    
    REM Sun Mon Tue Wed Thu Fri Sat
    REM Sunday Monday Tuesday Wednesday Thursday Friday Saturday  
    
    0 讨论(0)
  • 2020-11-27 20:42

    Another spin on this topic. The below script displays a few days around the current, with day-of-week prefix.

    At the core is the standalone :dpack routine that encodes the date into a value whose modulo 7 reveals the day-of-week per ISO 8601 standards (Mon == 0). Also provided is :dunpk which is the inverse function:

    @echo off& setlocal enabledelayedexpansion
    rem 10/23/2018 daydate.bat: Most recent version at paulhoule.com/daydate
    rem Example of date manipulation within a .BAT file.
    rem This is accomplished by first packing the date into a single number.
    rem This demo .bat displays dates surrounding the current date, prefixed
    rem with the day-of-week.
    
    set days=0Mon1Tue2Wed3Thu4Fri5Sat6Sun
    call :dgetl y m d
    call :dpack p %y% %m% %d%
    for /l %%o in (-3,1,3) do (
      set /a od=p+%%o
      call :dunpk y m d !od!
      set /a dow=od%%7
      for %%d in (!dow!) do set day=!days:*%%d=!& set day=!day:~,3!
      echo !day! !y! !m! !d!
    )
    exit /b
    
    
    rem gets local date returning year month day as separate variables
    rem in: %1 %2 %3=var names for returned year month day
    :dgetl
    setlocal& set "z="
    for /f "skip=1" %%a in ('wmic os get localdatetime') do set z=!z!%%a
    set /a y=%z:~0,4%, m=1%z:~4,2% %%100, d=1%z:~6,2% %%100
    endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b
    
    
    rem packs date (y,m,d) into count of days since 1/1/1 (0..n)
    rem in: %1=return var name, %2= y (1..n), %3=m (1..12), %4=d (1..31)
    rem out: set %1= days since 1/1/1 (modulo 7 is weekday, Mon= 0)
    :dpack
    setlocal enabledelayedexpansion
    set mtb=xxx  0 31 59 90120151181212243273304334& set /a r=%3*3
    set /a t=%2-(12-%3)/10, r=365*(%2-1)+%4+!mtb:~%r%,3!+t/4-(t/100-t/400)-1
    endlocal& set %1=%r%& exit /b
    
    
    rem inverse of date packer
    rem in: %1 %2 %3=var names for returned year month day
    rem %4= packed date (large decimal number, eg 736989)
    :dunpk
    setlocal& set /a y=%4+366, y+=y/146097*3+(y%%146097-60)/36524
    set /a y+=y/1461*3+(y%%1461-60)/365, d=y%%366+1, y/=366
    set e=31 60 91 121 152 182 213 244 274 305 335
    set m=1& for %%x in (%e%) do if %d% gtr %%x set /a m+=1, d=%d%-%%x
    endlocal& set /a %1=%y%, %2=%m%, %3=%d%& exit /b
    
    0 讨论(0)
  • 2020-11-27 20:46

    I have this solution working for me:

    Create a file named dayOfWeek.vbs in the same dir where the cmd file will go.

    dayOfWeek.vbs contains a single line:

    wscript.stdout.write weekdayname(weekday(date))
    

    or, if you want day number instead of name:

    wscript.stdout.write weekday(date)
    

    The cmd file will have this line:

    For /F %%A In ('CScript dayOfWeek.vbs //NoLogo') Do Set dayName=%%A
    

    Now you can use variable dayName like:

    robocopy c:\inetpub \\DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs
    
    0 讨论(0)
  • 2020-11-27 20:58

    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);
    
    0 讨论(0)
提交回复
热议问题