SET /A posn=100%mth%%%100*3-3
... you have several options:
without delayed expansion
call set mmm=%%mths:~%posn%,3%%
The variables are expanded in two passes because of the CALL. After the first pass %posn% is expanded to the number and %%mths%% becomes %mths% which is expanded on the second pass.
with delayed expansion
Either technique above is all you need for your example. But sometime you might find yourself in a position where you need both mths and posn to be expanded with delayed expansion (such as if posn were being set within a for loop.
The following will NOT work (assuming delayed expansion is already enabled)
It is much like your original dilemma.
The solution in this case is:
for %%n in (!posn!) do set mmm=!mths:~%%n,3!
One other point - expanding to a substring is not dependent on the set command. You can use the technique at any point. For example, if all you wanted to do was display the month without setting a variable, you could simply use:
call echo %%mths:~%posn%,3%%
Hope that helps