Reputation: 82
Bit of a weird one. I've been messing around with windows batch and time comparisons to schedule a task. Now I know there's a million better ways to do it, but our work machines are pretty locked down, so a batch script seems like the easiest way to actually achieve what I needed without some crazy workaround. I'm also well aware that the idea behind this is pretty gross. I'm not looking for perfection here, I'm just looking for it to work.
Basically at 17:00 on the 23rd November, I needed to move a file from one place to another. Problem is that I wouldn't actually be physically present at that time due to some other commitments, so I figured a batch script that was stuck in a loop of nothing until a certain date/time would work. So I cobbled together the following quickly the night before:
:dateloop
if %date% LSS 23/11/2019 goto dateloop
:timeloop
if %time% LSS 17:00 goto timeloop
<xcopy operation goes here>
And ran it overnight. So imagine my surprise when I came to my machine the next morning to check my emails and noticed that the file had been moved. Thankfully I was able to revert the file and rescheduled my day to do it manually.
I ran some tests last night, making sure that the script didn't exit upon completion so I could read the echo output. And it turns out that it was all running fine until 2:00, when the script decided "yes, this is after 17:00".
I could test it again tonight, and I do plan to, with the time format written out the long way (17:00:00:00) but I was wondering if anyone could confirm before I do, as that's a good while away, if this is the cause of my problem?
Upvotes: 2
Views: 66
Reputation: 6123
If you type IF /?
at the command prompt, the help text will include this:
If Command Extensions are enabled IF changes as follows: IF [/I] string1 compare-op string2 command IF CMDEXTVERSION number command IF DEFINED variable command where compare-op may be one of: EQU - equal NEQ - not equal LSS - less than LEQ - less than or equal GTR - greater than GEQ - greater than or equal and the /I switch, if specified, says to do case insensitive string compares. The /I switch can also be used on the string1==string2 form of IF. These comparisons are generic, in that if both string1 and string2 are both comprised of all numeric digits, then the strings are converted to numbers and a numeric comparison is performed.
As you can see, comparison is on strings unless the strings to compare contain only numeric digits. As time contains the non-numeric characters ":" and ".", the time is treated as a string, and of course "2" comes after the "1" from "17:00".
However, with the command echo [%time%]
you'll notice that if the time is less than 10, it adds a space at the front. Therefore, you can get correct results with a string comparison as long as you take the space into account. So replace your problematic statement with the following one:
if "%time%" LSS "17:00" goto timeloop
That should fix it.
Upvotes: 1
Reputation: 57282
If compares strings alphabetically or numbers.
You need to rework your code and compare times as numbers. So you also need a reliable way to get date parts as numbers - date
and time
variables are not suitable because they can be in different formats depending on your settings.
Try this instead:
@echo off
::GOTO comment macro
set "[:=goto :]%%"
::brackets comment macros
set "[=rem/||(" & set "]=)"
for /f %%# in ('wMIC Path Win32_LocalTime Get /Format:value') do @for /f %%@ in ("%%#") do @set %%@
%[:%
echo %day%
echo %DayOfWeek%
echo %hour%
echo %minute%
echo %month%
echo %quarter%
echo %second%
echo %weekinmonth%
echo %year%
%:]%
:dateloop
if %year%%month%%day% LSS 20191132 goto dateloop
:timeloop
if %hour%%minute% LSS 1700 goto :timeloop
Upvotes: 1