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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11364147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 09:40:13  来源:igfitidea点击:

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

windowsscriptingbatch-file

提问by Ed Heal

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).

我有一个每天运行的 Windows 批处理文件。希望将数据记录到文件中并希望轮换它(即最多具有过去 7 天的数据)。

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

查看命令DATEDELIMS- 无法找到解决方案。

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

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

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

或者我必须求助于一些更好的shell脚本。

回答by PA.

%DATE%is not your friend. Because the %DATE%environment variable (and the DATEcommand) returns the current date using the Windows short date formatthat 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.

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

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 FORcommand.

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

    this is the method I recommend.

  1. 您可能想通过将注册表值中的区域设置更改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
    

    但是这个方法有两个问题:

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

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

  2. 使用WMIC Win32_LocalTime,它以一种方便的方式返回日期以直接用FOR命令解析它。

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

    这是我推荐的方法。

回答by npocmaka

few more ways:

还有几种方法:

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

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- works on every windows machine (but creates a small temp file).Function provided by carlos:

2. MAKECAB- 适用于每台 Windows 机器(但会创建一个小的临时文件)。卡洛斯提供的功能:

@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:

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(must be saved as .bat):

4. .bat/jscript 混合(必须另存为.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)

5. .bat/vbscript 混合(必须另存为.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.powershellcan be downloaded from microsoft.Available by default in everything form win7 and above:

6. PowerShell中可以microsoft.Available默认一切形式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.WMICalready used as an answer but just want to have a full reference.And with cleared <CR>:

7. WMIC已经用作答案,但只是想有一个完整的参考。并清除<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):

9.自编译jscript.net(必须另存为.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);

回答by Aacini

@ECHO OFF
REM GET DAY OF WEEK VIA DATE TO JULIAN DAY NUMBER CONVERSION
REM ANTONIO PEREZ AYALA
REM GET MONTH, DAY, YEAR VALUES AND ELIMINATE LEFT ZEROS
FOR /F "TOKENS=1-3 DELIMS=/" %%A IN ("%DATE%") DO SET /A MM=10%%A %% 100, DD=10%%B %% 100, YY=%%C
REM CALCULATE JULIAN DAY NUMBER, THEN DAY OF WEEK
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.

DOW 星期日为 0,星期一为 1,以此类推。

回答by Aacini

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

我认为我的第一个答案给出了正确的星期几作为 0 到 6 之间的数字。但是,因为您没有说明为什么这个答案没有给出您想要的结果,我只能猜测原因。

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 forcommand.

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

@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:

编辑:下面的版本将星期几插入为 3 个字母的短名称:

@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

安东尼奥

回答by David Kroukamp

This turned out way more complex then I first suspected, and I guess that's what intrigued me, I searched every where and all the methods given wouldnt work on Windows 7.

事实证明,这比我最初怀疑的要复杂得多,我想这就是让我感兴趣的地方,我搜索了所有地方,所有给出的方法都不适用于 Windows 7。

So I have an alternate solution which uses a Visual Basic Script.

所以我有一个使用 Visual Basic 脚本的替代解决方案。

The batch creates and executes the script(DayOfWeek.vbs), assigns the scripts output (Monday, Tuesday etc) to a variable (dow), the variable is then checked and another variable (dpwnum) assigned with the days number, afterwards the VBS is deleted hope it helps:

批处理创建并执行脚本(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

EDIT:

编辑:

Though I turned to VBS, It can be done in pure batch, took me a while to get it working and a lot of searching lol, but this seems to work:

虽然我转向 VBS,但它可以以纯批处理方式完成,我花了一段时间才让它工作并进行了大量搜索,哈哈,但这似乎有效:

 @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

The only caveat for you on the above batch is that its day of weeks are from 1-7 and not 0-6

在上述批次中唯一需要注意的是它的星期几是从 1-7 而不是 0-6

回答by Dan

This works for me

这对我有用

FOR /F "tokens=3" %%a in ('robocopy ^|find "Started"') DO SET TODAY=%%a

回答by delliottg

This is not my work (well, I modified it slightly from the example), and it's late to the game, but this works on Server 2003 for me;

这不是我的工作(好吧,我从示例中稍微修改了它),而且游戏已经晚了,但这对我来说适用于 Server 2003;

@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

Citation: TechSupportForum

引用:技术支持论坛

回答by Ted Waterbury

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

首先 - 复制 CON SETUPDAY.001 SET WORKDAY=​​^Z(非常重要 - 没有 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

在脚本中使用 %WEEKDAY%

回答by Manuel Alves

I have this solution working for me:

我有这个解决方案对我有用:

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

在 cmd 文件所在的同一目录中创建一个名为 dayOfWeek.vbs 的文件。

dayOfWeek.vbscontains a single line:

dayOfWeek.vbs包含一行:

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:

cmd 文件将包含以下行:

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

Now you can use variable dayNamelike:

现在你可以使用变量dayName像:

robocopy c:\inetpub \DCStorage1\Share1\WebServer\InetPub_%dayName% /S /XD history logs

回答by user2316634

I am in the US. I can run this code in Windows 7, Windows 2008 R2, Windows Server 2003, Windows XP (All OS's are current with Windows Updates and patches). All with short date setting without ddd (or dddd) (day of week).

我在美国。我可以在 Windows 7、Windows 2008 R2、Windows Server 2003、Windows XP(所有操作系统都是最新的 Windows 更新和补丁)中运行此代码。所有短日期设置都没有 ddd(或 dddd)(星期几)。

@echo off
for /f %%a in ('date /t') do set DAY=%%a
echo.
echo The Day Is: %DAY%
echo.

If today is Thursday, it would output "The Day Is: Thu".

如果今天是星期四,它会输出“The Day Is: Thu”。

This returns the day on all 4 Windows versions I have tested on. And only the day. When I changed my short date setup to be "ddd, M/d/yyyy", my output would show the day with a comma (e.g. Thu,) which tells me this code does use the short date format. But what also may be happening is that if the short date does not contain the day of week, it may look to the long date format which on all 4 machines I tested on, have dddd in the format.

这将返回我测试过的所有 4 个 Windows 版本的日期。而且只有这一天。当我将短日期设置更改为“ddd, M/d/yyyy”时,我的输出将显示带有逗号的日期(例如 Thu,),它告诉我此代码确实使用了短日期格式。但也可能发生的情况是,如果短日期不包含星期几,它可能会查看我测试过的所有 4 台机器上的长日期格式,格式为 dddd。