Jdate2date macro - missing operand?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Acy Forsythe
Posts: 126
Joined: 10 Jun 2011 10:30

Jdate2date macro - missing operand?

#1 Post by Acy Forsythe » 11 Aug 2011 13:53

macro.Jdate works correctly, but macro.Jdate2Date gives a "missing operand" error, but finishes and provides the wrong date. I copied the formulas from here: http://www.dostips.com/DtCodeCmdLib.php#Function.jdate


Code: Select all

@ECHO OFF &Setlocal DisableDelayedExpansion
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%== Setting LF ==%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET LF=^


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%== Defining Macros ==%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET ^"\n=^^^%LF%%LF%^%LF%%LF%^^"


SET NL=^^^%LF%%LF%^%LF%%LF%


SET macro_Call=FOR /f "tokens=1-26" %%a IN


SET macro.Jdate=DO (%\n%
  SetLocal EnableDelayedExpansion%\n%
  SET DateStr=%%~a^&IF "%%~a"=="" set "DateStr=%DATE%"%\n%
  FOR /F "skip=1 tokens=2-4 delims=(-)" %%A in ('"echo.|date"') do (%\n%
    FOR /F "tokens=1-3 delims=/.- " %%G in ("!DateStr:* =!") do (%\n%
        SET %%A=%%G^&SET %%B=%%H^&SET %%C=%%I))%\n%
  SET /a "yy=10000!yy! %%10000,mm=100!mm! %% 100,dd=100!dd! %% 100"%\n%
  IF !yy! LSS 100 SET /a yy+=2000%\n%
  SET /a JD=!dd!-32075+1461*(!yy!+4800+(!mm!-14^^)/12^^)/4+367*(!mm!-2-(!mm!-14^^)/12*12^^)/12-3*((yy+4900+(!mm!-14^^)/12^^)/100^^)/4%\n%
  FOR %%v IN (!JD!) DO ENDLOCAL^&IF "%%~b" neq "" (set "%%~b=%%v") else echo %%v%\n%
)


SET macro.Jdate2Date=DO (%\n%
  SetLocal EnableDelayedExpansion%\n%
  SET /a L=%%~a+68569,N=4*!L!/146097,L=!L!-(146097*!N!+3^^)/4,I=4000*(!L!+1^^)/1461001%\n%
  SET /a L=!L!-1461*!I!/4+31,J=80*!L!/2447,K=!L!-2447*!J!/80,L=!J!/11%\n%
  SET /a J=!J!+2-12*!L!,I=100*(!N!-49^^)+!I!+!L!%\n%
  SET /a YYYY=!I!,MM=100+!J!,DD=100+!K!%\n%
  SET MM=!MM:~-2!%\n%
  SET DD=!DD:~-2!%\n%
  SET "DOUT=!MM!/!DD!/!YYYY!"%\n%
  FOR %%v IN (!DOUT!) DO ENDLOCAL^&IF "%%~b" neq "" (set "%%~b=%%v") else echo %%v%\n%
)


Setlocal EnableDelayedExpansion
:: Calling Macros

%macro_CALL% ("%TODAY% NEWJD") %macro.Jdate%

ECHO NEWJD= %NEWJD%


%macro_CALL% ("%NEWJD% NEWDATE") %macro.Jdate2Date%

ECHO %NEWDATE%

pause

Endlocal &exit /b



EDIT:

Added relative parts of the script for trouble-shooting purposes, Out of context the macros wouldn't mean much to most.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Jdate2date macro - missing operand?

#2 Post by dbenham » 14 Aug 2011 21:03

Oooh - you were so close :)

When using SET /A, you don't need to expand the variables - the SET /A command will do it for you.

In your Jdate2Date macro you MUST NOT expand the variables because computations after the comma depend on prior computations.

This fails:

Code: Select all

  SET /a L=%%~a+68569,N=4*!L!/146097,L=!L!-(146097*!N!+3^^)/4,I=4000*(!L!+1^^)/1461001%\n%
because the computation of N depends on the value of !L!. But !L! is undefined when it is expanded prior to the execution of the SET command.

This works:

Code: Select all

  SET /a "L=(%%~a)+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001"%\n%
I added parenthesis around %%~a so that you can pass in an arithmetic expression, possibly involving variables. Remember - you don't need to expand the variables being passed in either because it is read by SET /A:!:

But one other thing - this line in Jdate must be preserved as written: It is designed to prevent the values from being interpreted as octal in case the dates are 0 prefixed. In this case we MUST expand before SET /A sees the numbers.

Code: Select all

  SET /a "yy=10000!yy! %%10000,mm=100!mm! %% 100,dd=100!dd! %% 100"%\n%


Here is your code with unwanted !var! expansion removed. I also modified it so that the BAT script expects the date in the %1 variable. If it doesn't exist then it will use the current date.

Code: Select all

@ECHO OFF
Setlocal DisableDelayedExpansion
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%== Setting LF ==%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET LF=^


:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%== Defining Macros ==%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET ^"\n=^^^%LF%%LF%^%LF%%LF%^^"


SET NL=^^^%LF%%LF%^%LF%%LF%


SET macro_Call=FOR /f "tokens=1-26" %%a IN


SET macro.Jdate=DO (%\n%
  SetLocal EnableDelayedExpansion%\n%
  SET DateStr=%%~a^&IF "%%~a"=="" set "DateStr=!DATE!"%\n%
  FOR /F "skip=1 tokens=2-4 delims=(-)" %%A in ('"echo.|date"') do (%\n%
    FOR /F "tokens=1-3 delims=/.- " %%G in ("!DateStr:* =!") do (%\n%
        SET %%A=%%G^&SET %%B=%%H^&SET %%C=%%I))%\n%
  SET /a "yy=10000!yy! %%10000,mm=100!mm! %% 100,dd=100!dd! %% 100"%\n%
  IF !yy! LSS 100 SET /a yy+=2000%\n%
  SET /a JD=dd-32075+1461*(yy+4800+(mm-14^^)/12^^)/4+367*(mm-2-(mm-14^^)/12*12^^)/12-3*((yy+4900+(mm-14^^)/12^^)/100^^)/4%\n%
  FOR %%v IN (!JD!) DO ENDLOCAL^&IF "%%~b" neq "" (set "%%~b=%%v") else echo %%v%\n%
)


SET macro.Jdate2Date=DO (%\n%
  SetLocal EnableDelayedExpansion%\n%
  SET /a "L=(%%~a)+68569,N=4*L/146097,L=L-(146097*N+3)/4,I=4000*(L+1)/1461001"%\n%
  SET /a "L=L-1461*I/4+31,J=80*L/2447,K=L-2447*J/80,L=J/11"%\n%
  SET /a "J=J+2-12*L,I=100*(N-49)+I+L"%\n%
  SET /a "YYYY=I,MM=100+J,DD=100+K"%\n%
  SET MM=!MM:~-2!%\n%
  SET DD=!DD:~-2!%\n%
  SET "DOUT=!MM!/!DD!/!YYYY!"%\n%
  FOR %%v IN (!DOUT!) DO ENDLOCAL^&IF "%%~b" neq "" (set "%%~b=%%v") else echo %%v%\n%
)

Setlocal EnableDelayedExpansion
:: Calling Macros

%macro_CALL% (""%~1" NEWJD") %macro.Jdate%

ECHO NEWJD= %NEWJD%


%macro_CALL% ("NEWJD NEWDATE") %macro.Jdate2Date%

ECHO %NEWDATE%

pause

Endlocal &exit /b


Dave Benham

Acy Forsythe
Posts: 126
Joined: 10 Jun 2011 10:30

Re: Jdate2date macro - missing operand?

#3 Post by Acy Forsythe » 15 Aug 2011 10:55

Arrrghh!

I feel like Maxwell Smart.

But at least I learned things... Set /a will expand variables on it's own, Sometimes you don't want it to, and enclosing your SET statement in "" allows you to get rid of unsightly escape characters :)

I can finally get rid of those 65 lines of functions figuring out what yesterday's date was and replace them Jdate macros!

Thanks again Dave and Thanks DosTips for providing the functions, this is significantly easier than rolling back months and accounting for leap-years etc...

Post Reply