将windows批处理文件变量设置为星期几

将windows批处理文件变量设置为星期几,windows,scripting,batch-file,Windows,Scripting,Batch File,我有一个每天运行的windows批处理文件。希望将数据记录到文件中,并希望对其进行轮换(即,最多有7天的数据) 查看命令DATE和DELIMS——无法找到解决方案 是否有一个简单的解决方案来创建一个包含一周中某一天的文件名,即0表示星期一等 或者我必须使用更好的shell脚本。依赖于区域设置的版本:在某些环境中,以下内容将从日期中提取日期名称: set dayname=%date:~0,3% 它假定日期名称是%date%的第一部分。但是,根据机器设置,子字符串部分(~0,3)需要更改 这样的语

我有一个每天运行的windows批处理文件。希望将数据记录到文件中,并希望对其进行轮换(即,最多有7天的数据)

查看命令
DATE
DELIMS
——无法找到解决方案

是否有一个简单的解决方案来创建一个包含一周中某一天的文件名,即0表示星期一等


或者我必须使用更好的shell脚本。

依赖于区域设置的版本:在某些环境中,以下内容将从日期中提取日期名称:

set dayname=%date:~0,3%
它假定日期名称是
%date%
的第一部分。但是,根据机器设置,子字符串部分(
~0,3
)需要更改

这样的语句将转储到具有三个字符日名称的文件中:

set logfile=%date:~0,3%.log
echo some stuff > %logfile%
独立于区域设置的版本:如果您不需要它,那么另一种方法是编写一个打印星期几的小应用程序。然后使用批处理文件中该程序的输出。例如,下面的C应用程序打印
dayN
,其中N=0..6

#include <stdio.h>
#include <time.h>

int main( int argc, char* argv[] )
{
   time_t curtime;
   struct tm * tmval;

   time( &curtime );
   tmval = localtime( &curtime );
   // print dayN.  Or use a switch statement and print
   // the actual day name if you want
   printf( "day%d", tmval->tm_wday );
}

%DATE%
不是你的朋友。因为
%DATE%
环境变量(以及
DATE
命令)使用完全可无限定制的Windows短日期格式返回当前日期。一个用户可能会将系统配置为返回2012年6月7日,而另一个用户可能会选择Fri060712。使用
%DATE%
对于一个BAT程序员来说是一场彻头彻尾的噩梦

有两种可能的方法来解决此问题:

  • 通过将注册表值
    HKCU\Control Panel\International\sShortDate
    中的区域设置更改为可识别的格式,您可能会试图临时更改短日期格式。然后访问
    %DATE%
    以获得所需格式的日期;最后将格式恢复为原始用户格式。像这样的

    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
    
    但这种方法有两个问题:

    • 它为其本地特定目的篡改全局注册表值,因此它可能会干扰其他进程或用户任务,这些进程或任务同时以短日期格式查询日期,如果同时运行,则包括它自己

    • 它以本地语言返回一周中三个字母的日期,在不同的系统或不同的用户中可能会有所不同

  • 使用WMIC Win32_LocalTime,它以方便的方式返回日期,并使用
    FOR
    命令直接解析日期

    FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (
      set DOW=%%A
    )
    
    @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
    
    这是我推荐的方法


  • 道琼斯指数周日为0,周一为1,等等。

    我想我的第一个答案给出了一周中正确的一天,数字在0到6之间。然而,因为你没有说明为什么这个答案没有给出你想要的结果,我只能猜测原因

    下面的批处理文件每天创建一个日志文件,名称中有一个数字,0=星期天,1=星期一,等等。。。程序假定
    echo%date%
    以MM/DD/YYYY格式显示日期;如果不是这样,只需在
    for
    命令中更改mm和dd变量的位置即可

    FOR /F "skip=1" %%A IN ('WMIC Path Win32_LocalTime Get DayOfWeek' ) DO (
      set DOW=%%A
    )
    
    @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
    
    如果这不是您想要的,请指出问题,以便我可以解决它

    编辑:以下版本获取独立于区域设置的日期部分:

    @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
    
    @echo关闭
    对于/F“跳过=1标记=2-4标记=(/)”%%A in('date^日-%dow%.txt
    
    编辑:以下版本以三个字母的短名称插入星期几:

    @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
    
    @echo关闭
    对于/F“跳过=1标记=2-4标记=(/)”%%A in('date^日-%dow%.txt
    
    问候,


    Antonio

    这比我最初怀疑的要复杂得多,我想这正是我感兴趣的地方,我搜索了所有地方,所有给出的方法在Windows 7上都不起作用

    因此,我有一个替代解决方案,它使用VisualBasic脚本

    批处理创建并执行脚本(DayOfWeek.vbs),将脚本输出(星期一、星期二等)分配给一个变量(dow),然后检查该变量,并为另一个变量(dpwnum)分配天数,然后删除vbs,希望有帮助:

    @echo off
    
    REM Create VBS that will get day of week in same directory as batch
    echo wscript.echo WeekdayName(Weekday(Date))>>DayOfWeek.vbs
    
    REM Cycle through output to get day of week i.e monday,tuesday etc
    for /f "delims=" %%a in ('cscript /nologo DayOfWeek.vbs') do @set dow=%%a
    
    REM delete vbs
    del DayOfWeek.vbs
    
    REM Used for testing outputs days name
    echo %dow%
    
    REM Case of the days name is important must have a capital letter at start
    REM Check days name and assign value depending
    IF %dow%==Monday set downum=0
    IF %dow%==Tuesday set downum=1
    IF %dow%==Wednesday set downum=2
    IF %dow%==Thursday set downum=3
    IF %dow%==Friday set downum=4
    IF %dow%==Saturday set downum=5
    IF %dow%==Sunday set downum=6
    
    REM print the days number 0-mon,1-tue ... 6-sun
    echo %downum%
    
    REM set a file name using day of week number
    set myfile=%downum%.bak
    
    echo %myfile%
    
    pause
    exit
    
    编辑:

    虽然我转向VBS,但它可以在纯批处理中完成,我花了一些时间让它工作,并进行了大量搜索lol,但这似乎是可行的:

     @echo off
    SETLOCAL enabledelayedexpansion
    SET /a count=0
    FOR /F "skip=1" %%D IN ('wmic path win32_localtime get dayofweek') DO (
        if "!count!" GTR "0" GOTO next
        set dow=%%D
        SET /a count+=1
    )
    :next
    echo %dow%
    pause
    
    对于上述批次,您唯一需要注意的是,其周数为1-7天,而不是0-6天

    Rem Remove the end comma and add /A to set for this line worked for me.
    set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10 
    
    1.Robocopy在XP中不可用,但可以通过win 2003资源工具包下载。也可能取决于本地化:

    @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-在每台windows计算机上工作(但创建一个小临时文件)

    3.W32TM-使用Vista中引入的命令开关,因此无法在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(必须另存为.bat):

    5..bat/vbscript混合版

    6.powershell可从microsoft下载。默认情况下,win7及以上版本的所有版本均可用:

    @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已经用作答案,但只想有一个答案
     @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());
    
     :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
    
    @echo off
    setlocal
    for /f %%d in ('"powershell (Get-Date).DayOfWeek.Value__"') do set dow=%%d
    
    echo day of the week : %dow%
    endlocal
    
    @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
    
    @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);
    
    @echo off
    for /f %%a in ('date /t') do set DAY=%%a
    echo.
    echo The Day Is: %DAY%
    echo.
    
    FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a
    
    wscript.stdout.write weekdayname(weekday(date))
    
    wscript.stdout.write weekday(date)
    
    For /F %%A In ('CScript dayOfWeek.vbs //NoLogo') Do Set dayName=%%A
    
    robocopy c:\inetpub \\DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs
    
    c:\>vol | date
    The current date is: Mon 2014-12-01
    
    @echo off
    
    vol | date | find /i "sun" > nul 
    if not errorlevel 1 goto SUN
    
    vol | date | find /i "mon" > nul 
    if not errorlevel 1 goto MON
    
          # write block for other week days    
    
    goto END
    
    :SUN
    set fname="sun"
    goto BACKUP
    
    :MON
    set fname="mon"
    goto BACKUP
    
          # write block for other week days
    
    :BACKUP
    echo %fname%
    
    :END
    
    @echo off  
    set daysofweek=Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday  
    for /F "skip=2 tokens=2-4 delims=," %%A in ('WMIC Path Win32_LocalTime Get DayOfWeek /Format:csv') do set daynumber=%%A  
    for /F "tokens=%daynumber% delims=," %%B in ("%daysofweek%") do set day=%%B
    
    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%
    
    @echo off
    ::Invoke a javascript function using mhta
    
    set jsfunc=new Date().getDay()
    set dialog="about:<script>resizeTo(0,0);new ActiveXObject('Scripting.FileSystemObject').
    set dialog=%dialog%GetStandardStream(1).WriteLine(%jsfunc%);close();</script>"
    
    for /f "tokens=* delims=" %%p in ('mshta.exe %dialog%') do set ndow=%%p
    
    ::get dow string from array of strings  
    for /f "tokens=%ndow%"  %%d in ("Mon Tue Wed Thu Fri Sat Sun") do set dow=%%d 
    
    echo dow is : %ndow%  %dow%
    pause
    
    rem Make the win32_localtime output all one line, though some versions may contain blank lines as well.
    rem So ignore blank lines and just pick up the number after the equal sign.
    for /f "delims== tokens=2" %%a in ('wmic path win32_localtime get dayofweek /format:list') do (
        rem Increment the DOW as it is documented to be a zero-based index starting with Sunday.
        set /a DayOfWeekIndex=%%a+1
    )
    rem Also get name day of week. The DOW coming in is now a one-based index.
    rem This is used to reference the "array" of week day names.
    set DayOfWeekNames=Sun Mon Tue Wed Thu Fri Sat
    for /f "tokens=%DayOfWeekIndex%" %%b in ("%DayOfWeekNames%") do (
        set DayOfWeekName=%%b
    )
    
    @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  
    
    @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