У меня есть процесс, который я запускаю из командного файла, и я хочу запускать его только в определенный день недели.
Можно ли получить день недели?
Все примеры, которые я нашел, каким-то образом полагаются на "date / t", чтобы вернуть "Friday, 12/11/2009", однако на моей машине "date / t" возвращает "12/11/2009". Нет буднего дня.
Я уже проверил "региональные настройки" для своей машины, и длинный формат даты включает день недели. Краткий формат даты - нет, но я бы не стал его менять, так как это повлияет на множество вещей, которые я делаю.
Я немного опоздал на эту вечеринку, но это подскажет вам день недели:
wmic путь win32_localtime получить dayofweek
Используйте пакет для цикла для получения выходных данных, и у вас есть проверяемое условие для дня недели.
Роб
Вот командный файл, который будет содержать всю информацию о дате и времени в переменных, но это зависит от того, установлен ли на вашем компьютере соответствующий формат даты. Кроме того, может потребоваться корректировка порядка в зависимости от местного формата даты, я не уверен.
@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%
Вам нужен бит в% WD%.
Вот правильный ответ для сценария BAT в современной системе:
@echo off
for /f %%i in ('powershell ^(get-date^).DayOfWeek') do set dow=%%i
echo %dow%
Выходы:
Saturday
Использование:
@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
Я использовал это для ПК, которые автоматически загружаются ежедневно из BIOS, у которых нет возможности исключить выходные.
Кроме того: ACPI - более надежный способ сделать это, и позволяет использовать фиктивный сценарий BAT, такой как exit
для использования в запланированной задаче Windows с выбранными днями, используя Разбудите компьютер для выполнения этой задачи вариант.
Пакетная обработка не может сделать это легко. Это требует большого количества функций командной строки с командой date. Есть несколько способов добиться того, что вам нужно, но больше всего мне интересно, почему встроенный планировщик задач не подходит? Он позволяет указать дни, в которые он должен запускаться, и в какое время:
Вы также можете использовать VBScript:
wscript.stdout.writeline weekdayname(weekday(date))
Затем запустите его:
C:\Documents and Settings\Administrator>cscript /nologo dayofweek.vbs Wednesday
Вы можете легко использовать логику if / else в VBScript, тогда ваш код VBScript будет выполнять пакетные файлы в зависимости от дня, и наоборот (иметь пакетный вызов VBScript).
Мой ответ основан на ответе Роба, но он просто повторяет будний день, а вопрос заключался в том, как изменить ход сценария в зависимости от дня недели (именно то, что я тоже хотел сделать). Что ж, это оказалось менее простым, чем кажется, потому что каким-то образом FOR
цикл получает две строки для обработки вместо одной, а вторая (которая кажется пустой) прерывает выполнение скрипта.
Единственный FOR
цикл, который действительно сработал для меня, не прерывая выполнение, следующий:
for /F "skip=1" %%I in ('wmic path win32_localtime get dayofweek') do (set /a dow=%%I 2>NUL)
if %dow% geq 6 goto ok
echo You can run this script only on Saturday or Sunday
goto :eof
:ok
REM do more stuff here
В 2>NUL
часть подавляет ошибку, которая иначе была бы показана во время второго присваивания, а /a
имеет дело с одним пробелом, который добавляется из-за перенаправления.
@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
Теперь осталось только добавить нули к дню и месяцу, если любое из них меньше 10.
Это можно сделать простым расчетом
::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"
Благодаря предыдущей публикации Фила Свисс - это работает:
echo. | cmd /C date | find "current"
Примеры использования:
echo. | cmd /C date | find /i "Fri" && echo today is Friday
Или наоборот:
echo. | cmd /C date | find /i "Fri" || echo today is NOT Friday
Как насчет этого для Windows 2008, гораздо более элегантного. Также будет работать везде, где установлен PowerShell.
@for /F "tokens=1 delims=, " %%i In ('powershell date') do set dow=%%i
echo %dow%
Чтобы избежать перенаправления в текстовый файл, существует вариант FOR, который принимает командную строку. Вот:
@For / F "tokens = 4 delims = / -"% i In ('@Echo.^|Command / C Date ^ | Find / i "current" ') Do @Echo% i
Не забудьте использовать двойные знаки процента, если вы помещаете эту команду в сценарий dos. В моем примере я проверил общий символ разделителя даты - косую черту или тире.
Я предпочитаю это решение, поскольку это исключительно DOS, и мне не нужно полагаться на наличие WMI, PowerShell и т. Д. Или нет.
Если кому-то это нужно, это работает для меня в Windows 7 и 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%
Для Windows Server 2008 я бы выбрал один из предложенных выше методов Powershell.
На самом деле флагом для этого (2K8, 2K3, XP и т. Д.) Является КОРОТКИЙ формат даты.
В разделе «Язык и региональные стандарты» нажмите кнопку «Настроить». На вкладке ДАТА Измените формат КОРОТКОЙ даты на «М / д / гггг». Измените формат ДЛИННОЙ даты на «дддд, ММММ дд, гггг»
Затем появится День недели - чтобы проверить это, выполните это в командной строке dos: date / t. Результат должен быть таким: «Mon 01/31/2011»
Могу я процитировать то, что нашел в сети:
О проблеме ДОУ ...
Win 2000 отображает текущую дату под заголовком «День недели», но Win XP дает вам чистую дату в формате вашей страны без DOW. Это одна из маленьких неприятностей, влияющих на двух (почти) братьев, управляющих сисемами.
Чтобы обойти эту уловку, нужно принудительно использовать устаревший формат, отображаемый (эмулируемой) DOS
Echo.|Command /C Date|Find "current"
Это действительно работает, теперь вам просто нужно вытащить DOW из выходной строки, и все готово ...
это решение:
for /f %i in ('cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]') do set dayofweek=%i
Работает, когда вы используете эту команду из CMD, но если вы хотите использовать ее в файле BAT, вы должны использовать:
for /f %%i in ( 'cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]' ) do set dayofweek=%%i
потому что по-другому вы увидите: Неправильный синтаксис команды.
Еще один ответ, который делает именно это, используя 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%%
Решение, опубликованное Atntoni Gual, работает с обычным пакетом, но мы должны назначить некоторые переменные перед выполнением расчета.
Это можно сделать с помощью простого вычисления: получить число доу (1 = понедельник) из дд мм гг set / aa = (14-мм) / 12, yr = yy-a, m = mm + 12 * a-2, "dow = (дд + год + год / 4 года / 100 + год / 400 + 31 * м / 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"
#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 ($daylabel -eq 'Friday','Thursday','Wednesday'){
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
Я в США. Я могу запустить этот код в 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.
Если сегодня четверг, будет выведено «The Day Is: Thu».
Это возвращает день для всех 4 версий Windows, которые я тестировал. И только день. Когда я изменил настройку короткой даты на «ddd, M / d / yyyy», мой вывод будет показывать день с запятой (например, Thu), что говорит мне, что этот код действительно использует формат короткой даты. Но также может происходить то, что если короткая дата не содержит день недели, она может обращаться к длинному формату даты, который на всех 4 машинах, на которых я тестировал, имеет dddd в формате.
Хорошо, нашел ан ответ...
Я не мог найти способ использовать простые файлы BAT, но если у вас есть доступ к 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
Надеюсь, поможет...
РЕДАКТИРОВАТЬ: (для потенциальных людей, которые спотыкаются об этом) Это неприятно и некрасиво, и этого не следует делать, и другие ответы на этот вопрос лучше, если они относятся к вам. Если вам НУЖНО сделать это быстро и грязно в уже имеющемся командном файле, это может сработать для вас.
Даниэль
Я использую...
for /f %i in ('cmd /c wmic path win32_localtime get dayofweek^|findstr [0-9]') do set dayofweek=%i
... чтобы получить номер текущего дня.
for /f "skip=1" %%a in ('WMIC Path win32_LocalTime Get DayOfWeek') do if not defined dayNumber set dayNumber=%%a