2

I wish to use batch command to parse %date% variable, to get year/month/date, like this:

>echo %date
Tue 08/18/2015

I wish to parse %a=2015, %b=08, %c=18, so I have the .bat like below:

@echo off
rem Get current date and calculate DayOfWeek
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
   set /A mm=%%a, dd=%%b, yy=%%c
)

But it failed to execute, saying that:

Missing operator.

How to fix my .bat file? Thanks a lot.

Immanuel Kant
  • 517
  • 3
  • 8

3 Answers3

5

Using "delims=/", the first token in "Tue 08/18/2015" results to Tue 08. Use

@echo off
rem Get current date and calculate DayOfWeek
for /F "tokens=2-4 delims=/ " %%a in ("%date%") do (
    set /A "_mm=1%%a %% 100"
    set /A "_dd=1%%b %% 100"
    set /A _yy=%%c
)
set _

Output:

==>D:\bat\SO\32062701.bat
_dd=18
_mm=8
_yy=2015

The set /A "mm=1%%a %% 100" trick prevents from Invalid number. Numeric constants are either decimal (17), hexadecimal (0x11), or octal (021) error. Read entire set /? or http://ss64.com/nt/set.html for explanation on decimal (17) vs. hexadecimal (0x11) vs. octal (021) denotation of the same number.

The octal notation can be confusing - all numeric values that start with zeros are treated as octal but 08 and 09 are not valid octal digits. For example, SET /a _month=07 will return the value 7, but SET /a _month=09 will return an error.

1%%a means concatecation of strings 1 and (evaluated) %%a: results to 108 if %%a evaluates to 08. %% is batch notation of modulus operator. Hence, 1%%a %% 100 means the remainder after (integer) division of 108 by 100, i.e. 8.

To get your script locale independent, extract values from WMIC output rather:

wmic os get LocalDateTime | find "."

or try

wmic path Win32_LocalTime get /value
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • Thanks, I just don't quite catch the "set" trick. What does 1%%a mean? and what doest %% 100 mean? And what is the space inside "1%%a %% 100" actually mean? – Immanuel Kant Aug 18 '15 at 03:57
  • 1
    @ImmanuelKant - `1%%a` means take the value of %%a and stick a 1 in front of it. `%%` is the [modulus](https://en.wikipedia.org/wiki/Modular_arithmetic) operator. The spaces are unnecessary and merely personal preference, probably for readability. – SomethingDark Aug 18 '15 at 04:38
0

Parsing the %date% variable is unreliable because the format changes depending on the locale/regional/user settings on the machine.

This is one way to get a reliable date string.

@echo off

rem The four lines below will give you reliable YY DD MM YYYY HH Min Sec MS variables in XP Pro and higher.

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "MS=%dt:~15,3%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%" & set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%-%MS%"

echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause
foxidrive
  • 40,353
  • 10
  • 53
  • 68
0

If you just want to get the DayOfWeek in your computer, you have two simple solutions. The first one is to get it directly from the first word of your %date% variable "Tue 08/18/2015" :):

for /F %%a in ("%date%") do set dow=%%a

But if you want to perform the numeric calculation, you may use the method to convert a date into the Julian Day Number shown at this answer:

@echo off
setlocal

rem Modify next line accordingly to your locale format (this one use "Dow MM/DD/YYYY")
for /F "tokens=2-4 delims=/ " %%a in ("%date%") do set /A mm=1%%a-100, dd=1%%b-100, yyyy=%%c

rem Convert the Date to Julian Day Number, and get its Day Of Week (0=Sunday, ..., 6=Saturday)
set /A a=(mm-14)/12, jdn=(1461*(yyyy+4800+a))/4+(367*(mm-2-12*a))/12-(3*((yyyy+4900+a)/100))/4+dd-32075, dow=(jdn+1)%%7

rem Show the result
echo Day of week: %dow%

The set command use the trick explained in other answers in order to correctly get numbers greater than 07 that start with zero. For example, if the mont is 08, then set /A mm=1%%a-100 is set /A mm=108-100, that gives 8.

However, if you want to use this method on different computers, that may have different locale date formats, then you must use the method suggested by foxidrive.

Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108