10

I have a process I run from a batch file, and i only want to run it on a certain day of the week.
Is it possible to get the day of week?

All the example I found, somehow rely on "date /t" to return "Friday, 12/11/2009", however, in my machine, "date /t" returns "12/11/2009". No weekday there.

I've already checked the "regional settings" for my machine, and the long date format does include the weekday. The short date format doesn't, but i'd really rather not change that, since it'll affect a bunch of stuff I do.

Alexander Farber
  • 714
  • 4
  • 16
  • 38
Daniel Magliola
  • 1,402
  • 9
  • 20
  • 33

23 Answers23

14

I'm a little late to this party, but this will give you the day of week:

wmic path win32_localtime get dayofweek

Use a batch for loop to obtain the output, and you have a testable condition for the day of the week.

Rob

RobW
  • 2,766
  • 1
  • 17
  • 22
  • How to save that into a variable? – Saeed Neamati Oct 12 '15 at 08:02
  • 1
    Place it in a for loop - like: for /f "skip=1" %a in ('wmic path win32_localtime get dayofweek') do @echo %a . Remember to use %%a as the variable if you place it in a script. – RobW Oct 15 '15 at 18:06
9

Here's the correct answer for a BAT script on a modern system:

@echo off
for /f %%i in ('powershell ^(get-date^).DayOfWeek') do set dow=%%i
echo %dow%

Outputs:

Saturday

Usage:

@echo off
for /f %%i in ('powershell ^(get-date^).DayOfWeek') do set dow=%%i
if %dow% == Saturday goto shutdown
if %dow% == Sunday goto shutdown
exit

:shutdown
shutdown /s /f /t 90

I used this for PC's which auto-boot daily from BIOS, which don't have an option to exclude weekends.

Aside: ACPI is a more reliable way of doing this, and allows for a dummy BAT script such as exit to be used in a Windows Scheduled Task with specific days selected, using the Wake the computer to run this task option.

Danny Beckett
  • 178
  • 3
  • 14
6

Here's a batch file that will get all the date and time info into variables but it does depend on you having an appropriate date format set on your machine. Also, the order might need adjusting depending on the local date format, I'm not sure.

@echo off
for /F "tokens=1-4 delims=/ " %%i in ('date /t') do (
set WD=%%i
set D=%%j
set M=%%k
set Y=%%l
) 

for /F "tokens=1-4 delims=: " %%i in ('time /t') do (
set H=%%i
set Mn=%%j
set AP=%%k
)

if "%AP%"=="PM" set /A H=%H%+12

echo %WD% %D%/%M%/%Y% - %H%:%Mn%

The bit you want is in %WD%.

John Gardeniers
  • 27,262
  • 12
  • 53
  • 108
4

Batch can't do this easily. It requires a lot of command-line fu with the date command. There are a few ways to achieve what you're after, but most of all I'm wondering why the built-in Task Scheduler isn't an option? It allows you specify the days you want it to run and what time:

alt text

You could also use VBScript:

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

Then run it:

C:\Documents and Settings\Administrator>cscript /nologo dayofweek.vbs
Wednesday

You can easily use if/else logic in VBScript then have your VBScript code execute batch files depending on the day, and vice-versa (have batch call a VBScript).

Glorfindel
  • 1,213
  • 3
  • 15
  • 22
John T
  • 1,059
  • 1
  • 15
  • 19
  • I basically have A batch file that does a bunch of stuff (backups), and some of that stuff (HUGE folders that are not that important and don't change often), I want to only do it once a week to save hours of daily time. I CAN split the batch file into many and use scheduler to control this, but it makes everything much more complicated for me, since the things that I need to do weekly happen after some and also before some of the daily ones (in particular, I burn a DVD every day after the backup is done, and that has to happen AFTER the long running tasks are done (which is hard to estimate) – Daniel Magliola Dec 16 '09 at 15:54
  • A very workable solution can be to have the task scheduler create a flag file on the desired day(s). The main batch file can check for the existence of that flag file and change the processing accordingly. Don't forget to delete the flag file as well. – John Gardeniers Jan 31 '11 at 17:35
3
@echo off

:set the variables
for /f %%C in ('wmic path Win32_LocalTime Get Year^,Month^,Day^,Hour^,Minute^,Second /Format:List 2^>nul ^| find "="') do @set current%%C

:display the variables
set current

Now all that remains is to pre-pend zeros to the day and month if either of them are less than 10.

2

Incase anyone needs it, this works for for me on Windows 7 and XP...

echo.|command /C date|find /i "current" >%temp%\dow.txt
for /f "tokens=1-4 delims=/ " %%i in (%temp%\dow.txt) do set DOW=%%l
echo %DOW%

For Windows Server 2008 I'd go with one of the Powershell methods suggested above.

Ronnie
  • 21
  • 1
2

My answer is based on RobW's answer, but he simply echoes the weekday, while the question was how to change the course of the script depending on the weekday (exactly what I wanted to do too). Well, it turned out to be less simple than it sounds, because somehow the FOR loop gets two lines to process instead of one, and the second one (which seems to be empty) breaks the script execution.

The only FOR loop that actually worked for me without breaking execution is the following:

for /F "skip=1" %%I in ('wmic path win32_localtime get dayofweek') do (set /a dow=%%I 2>NUL)
if %dow% equ 6 goto ok
if %dow% equ 0 goto ok
echo You can run this script only on Saturday or Sunday
goto :eof
:ok
REM do more stuff here

The 2>NUL part suppresses the error that would otherwise be shown during the second assignment, while /a deals with the one space that gets added because of the redirection.

  • I think there's a small mistake in your code. Testing on my machine shows Sunday is 0 so `geq 6` means it's Saturday, not "Saturday or Sunday". (Or is this based on regional settings and different in the UK?) – rkagerer Jan 28 '21 at 02:40
  • @rkagerer You are absolutely correct. It's not based on regional settings, my code was simply wrong. I have corrected it. Thanks for noticing this. – Ronny D'Hoore Feb 04 '21 at 11:35
1

Actually the flag for this (2K8, 2K3, XP etc) is the SHORT date format.

Under Regional and Language options - click Customize button On the DATE tab Change the SHORT Date format to "M/d/yyyy" Change the LONG Date format to "dddd, MMMM dd, yyyy"

Then the Day of the week shows up - to test this execute this in a dos prompt: date /t The output should be like this "Mon 01/31/2011"

Pebkac
  • 11
  • 1
  • The suggested change to regional settings will do the trick, but it's not available if your regional setting is Canada... it works as described when region is set to US... and I wouldn't change it on a server for fear that something else will crap out. –  Feb 11 '13 at 21:29
1

To avoid having to redirect to a text file, there is a variation of the FOR which takes a command string. Here it is:

@For /F "tokens=4 delims=/- " %i In ( '@Echo.^|Command /C Date^|Find /i "current"' ) Do @Echo %i

Remember to use double percent signs if you put this command in a dos script. In my example, I checked for the common date delimiter character of forward slash or dash.

I prefer this solution as it is solely DOS without having to rely on whether WMI, PowerShell, etc being present or not.

MakStir
  • 11
  • 1
1

How about this one for Windows 2008, much more elegant. Also will work anywhere powershell is installed.

@for /F "tokens=1 delims=, " %%i In ('powershell date') do set dow=%%i
echo %dow%
jscott
  • 24,204
  • 8
  • 77
  • 99
Dru
  • 11
  • 1
1

Thanks to Phil Swiss previous posting - this works a treat :

echo. | cmd /C date | find "current"

Examples usage:

echo. | cmd /C date | find /i "Fri" && echo today is Friday

Or to reverse:

echo. | cmd /C date | find /i "Fri" || echo today is NOT Friday

jscott
  • 24,204
  • 8
  • 77
  • 99
ThankYou
  • 11
  • 1
  • 2
    The output from date depends on the Windows datetime settings so this may not work in some cases. For example on the server I'm currently working with the data command returns date as 2013-09-03. – Juha Palomäki Sep 03 '13 at 20:28
1

It can be done with a simple calculation

 ::get dow number (1=monday) from dd mm yy 
 set/a a=(14-mm)/12,yr=yy-a,m=mm+12*a-2,"dow=(dd+yr+yr/4-yr/100+yr/400+31*m/12)%%7"
1

May I quote something I found on the net:

About the DOW problem...

Win 2000 displays the current date by heading with the Day of Week, but Win XP gives you the bare date in your country format without DOW. This is one of the little annoiances affecting the two (almost) brothers operating sysyems.

To work around the trick is to force the legacy format displayed by (emulated) DOS

Echo.|Command /C Date|Find "current"

This really works, now you just have to fumble the DOW out of the outputstring and you're done...

Phil Swiss
  • 1,437
  • 9
  • 4
0

this solution:

for /f %i in ('cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]') do set dayofweek=%i

Works when you use this command from CMD but if you want to use it in BAT file you should use:

for /f %%i in ( 'cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]' ) do set dayofweek=%%i

because in another way you will see: The syntax of the command is incorrect.

0

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

@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".

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.

  • The fact that this works on your machine doesn't really answer the OP's question. – Katherine Villyard Feb 06 '14 at 19:11
  • I've run this on 4 different machines. Each with a different OS. One being a Desktop PC (Windows 7), Server 2003 on a Server, Server 2008 and XP on VMs. I just am pointing out that it works for me in all 4 environments on 4 different machines. – Scott Gehret Feb 06 '14 at 21:15
0
ECHO: I needed a more comprehensive solution using an array.
@ECHO OFF
setlocal EnableDelayedExpansion

ECHO :: Get DayOfWeek
ECHO :: Will return DayOfWeek=#
ECHO :: 
For /F "tokens=1 delims=| " %%a In ( 'wmic path win32_localtime get dayofweek /Value^|Find "DayOfWeek"' ) Do (
  Echo %%a
  set "str=%%a"
  ECHO :: Remove DayOfWeek=
  set "str=!str:~10,1!"
  ECHO !str!
)
ECHO.
ECHO :: Create vector with names of days (Index of Days)
for %%d in (Monday Tuesday Wednesday Thrusday Friday Saturday Sunday) do (
  set /A i=i+1
  set day[!i!]=%%d
  if !i!==!str! (
    ECHO :: If today what DayOfWeek is it?
    ECHO %%d
  )
)
ECHO :: 
ECHO.
ECHO :: This is how we get the value outside the loop
set index=!str!
echo(!day[%index%]! 
ECHO.
PAUSE
Frederik
  • 3,293
  • 3
  • 30
  • 46
NetDreamz
  • 1
  • 1
  • Please explain your code in detail since just posting a bunch of code with no explanation doesn't really help anybody – Frederik Mar 30 '17 at 15:00
0
#USE POWERSHELL:
cls
$Today = (Get-Date).DayOfWeek
$daylabel = $Today | select label,day |
        where dayofweek -eq 'friday' |
        select -ExpandProperty label
# End of week ( Saturday ) in OLE Automation date format.
$TimeStamp = Get-Date -Format o | foreach {$_ -replace ":", "."}
 <#
$TimeStamp
$Today
$daylabel
 #>
#Run all your scripts every day but friday
If ($daylabel -eq 'Friday'){
run script |out-file -filepath "filepath\'$timestamp.filename.txt" -Encoding UTF8
}
ELSE {do something else, like 'ECHO "No scripts will be run today."}

If you want to have multiple days to run add the values:

If ($daylabel -eq 'Friday','Thursday','Wednesday'){
  • The OP asked how to find the day of the week in a batch file. Please show the OP how to call powershell from a batch file or provide the answer as a batch file. – user5870571 Jan 17 '19 at 22:44
0

The solution posted by Atntoni Gual works on plain batch but we must assign some variables before doing the calculation

It can be done with a simple calculation ::get dow number (1=monday) from dd mm yy set/a a=(14-mm)/12,yr=yy-a,m=mm+12*a-2,"dow=(dd+yr+yr/4-yr/100+yr/400+31*m/12)%%7"

:: extract date from date command on OS with date format dd-mm-yyyy
for /F "tokens=1,2,3 delims=-" %%a in ('echo %date%') do (set dd=%%a & set mm=%%b & set yy=%%c)

::get dow number (1=monday) from dd mm yy 
set/a a=(14-%mm%)/12,yr=%yy%-a,m=%mm%+12*a-2,"dow=(%dd%+yr+yr/4-yr/100+yr/400+31*m/12)%%7"
Rui Paz
  • 1
  • 1
0

Just another answer that does exactly this by using wmic

@echo off
set "d1=Mon" & set "d2=Tue" & set "d3=Wed" & set "d4=Thu" & set "d5=Fri" & set "d6=Sat" & set "d7=Sun"
for /f %%i in ('wmic path win32_localtime get dayofweek ^| findstr /r /c:[1-7]') do call echo %%d%%i%%
Gerhard
  • 101
-1

Got same problem with W2008R2 server which worked accordingly before. Probably someone changed region settings for Short date. Did some testing with region settings for short date and now its working again:

I get:

  • when configured short date like MM/dd/yyyy: 02/10/2021

  • when configured short date like M/d/yyyy: wed 02/10/2021

Zrin
  • 597
  • 1
  • 5
  • 14
-2

I use...

for /f %i in ('cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]') do set dayofweek=%i

...to get the current day number.

Sven
  • 97,248
  • 13
  • 177
  • 225
  • you could avoid using "cmd /c" with : for /f %%i in ('wmic path win32_localtime get dayofweek ^| findstr [0-9]') do set dayofweek=%%i – Max Jan 26 '17 at 09:31
-2
for /f "skip=1" %%a in ('WMIC Path win32_LocalTime Get DayOfWeek') do if not defined dayNumber set dayNumber=%%a
mzhaase
  • 3,778
  • 2
  • 19
  • 32
Liviu
  • 1
  • 1
    It is a little bit "magician" answer: "insert this ... and it will work". A good answer always contains a meaningful explanation, too. – peterh Feb 24 '17 at 08:48
-2

Ok, found an answer...
I couldn't find a way using plain BAT files, but if you have access to powershell...

@echo off
powershell date > date.txt
find/i "Fri" date.txt  > nul
if errorlevel 1 goto SkipWeeklyTasks

Do your weekly stuff here

:SkipWeeklyTasks
del date.txt

Hope it helps...

EDIT: (for potential people stumbling on this) This is nasty and ugly, and shouldn't be done, and other answers to this question are better, if they apply to you. If you NEED to get this done quickly and dirty within a batch file you already have, this could work for you, though.

Daniel

Daniel Magliola
  • 1,402
  • 9
  • 20
  • 33
  • 2
    Urgh. Please. If you have to use PowerShell for this, then at least give back a result that's (a) independent of any locale settings [the day of week need not be present and it doesn't have to be in English] and (b) is easily parseable. So `powershell "&{[int](Get-Date).DayOfWeek}"` is probably the better answer and you can easily put that into an environment variable and compare it. – Joey Dec 16 '09 at 06:50
  • 3
    If your going to use powershell at all you might as well translate the whole script to powershell. – Zypher Dec 16 '09 at 07:11
  • Zypher, that's the obvious idea, of course :-) – Joey Dec 16 '09 at 07:44
  • Johannes: Yah, this is actually a problem I need to solve and get rid of as quickly as possible. It only needs to work in MY machine(s). Every extra second I spend making this more generic than I need is esentially wasted. Zypher: Yah, but I already had my batch file running and working, and I don't know much about PowerShell, I only wanted to add a section that only ran once a week, and again, get rid of it as quickly as possible. But what you're both saying IS definitely good advice in case someone reads this solution. – Daniel Magliola Dec 16 '09 at 15:56
  • If I remember an old script of mine I actually ended up with a VBScript file that returned the date to the BAT file. – Brent Pabst Jul 03 '12 at 20:29
  • Ugly and convoluted as hell. If you want to end up on http://thedailywtf.com, this sure is a good bet. – Massimo Feb 06 '14 at 22:21