Page 1 of 1

set variable 2012 (currentyear - 1)

Posted: 07 Jun 2013 15:33
by forumwurm
Hi there

I need to have a variable which contains the last year:

set year=2012

Here is what I have tested so far.

Code: Select all


set currentyear=%date:~6,4%

:CHANGE2LASTYEAR
set /A %currentyear%-1 >%temp%\year.txt
set /P year=<%temp%\year.txt




Actualy this is working in a dos window, but not in a script. (set /a) seems to be the issue.

Any ideas or other approaches?

thx4nfo
fw

Re: set variable 2012 (currentyear - 1)

Posted: 07 Jun 2013 15:55
by Acy Forsythe
I also had to change the date substring to 10,4 instead of 6,4.

Code: Select all


set currentyear=%date:~6,4%

:CHANGE2LASTYEAR
set /A currentyear-=1 >%temp%\year.txt
REM Or
REM set /A currentyear=%currentyear%-1 >%temp%\year.txt

set /P year=<%temp%\year.txt


Re: set variable 2012 (currentyear - 1)

Posted: 07 Jun 2013 19:41
by Aacini

Code: Select all

set /A year=%date:~-4% - 1

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 01:19
by forumwurm
@Aacini, thank you very much. works like a charm ;)

one other question. How can I simplify the same thing with the month? It is working as follows, but should be possible with 1-2 lines code instead of 12.


Code: Select all

set currentmonth=%date:~3,2%

if "%currentmonth%" == "01" (set month=05)
if "%currentmonth%" == "02" (set month=01)
if "%currentmonth%" == "03" (set month=02)
if "%currentmonth%" == "04" (set month=03)
if "%currentmonth%" == "05" (set month=04)
if "%currentmonth%" == "06" (set month=05)
if "%currentmonth%" == "07" (set month=06)
if "%currentmonth%" == "08" (set month=07)
if "%currentmonth%" == "09" (set month=08)
if "%currentmonth%" == "10" (set month=09)
if "%currentmonth%" == "11" (set month=10)
if "%currentmonth%" == "12" (set month=11)



set /A month=%date:~3,2% - 1

This works, but I need as output not 1 but 01 (everytime 2 digits).

Even for January 01-1 = 0 or 00 would be fine. I can do the year check with 0 as follows:

if %month% EQU 0 (set /A year=%date:~-4% - 1) else (set /A year=%date:~-4%)

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 03:20
by foxidrive
Here's a method to extract a date before today, or ahead of today.

Code: Select all

:: Date foward & backward
@echo off
if "%~2"=="" (
echo to get todays date use         call "%~n0" today 0
echo to get yesterdays date use     call "%~n0" today -1
echo to get 25 days before 19441213 call "%~n0" 1944/12/13 -25
echo to get 1250 days in the future call "%~n0" today 1250
echo.
echo Add a third parameter if you want a separator in the date string
echo EG: to use - as in YYYY-MM-DD for today's date
echo     call "%~n0" today 0 -
echo.
pause
goto :EOF)

set date1=%1
set qty=%2
set separator=%~3
if /i "%date1%" EQU "TODAY" (set date1=now) else (set date1="%date1%")
echo >"%temp%\%~n0.vbs" s=DateAdd("d",%qty%,%date1%)
echo>>"%temp%\%~n0.vbs" WScript.Echo year(s)^&_
echo>>"%temp%\%~n0.vbs"         right(100+month(s),2)^&_
echo>>"%temp%\%~n0.vbs"         right(100+day(s),2)
for /f %%a in ('cscript //nologo "%temp%\%~n0.vbs"') do set result=%%a
del "%temp%\%~n0.vbs"
endlocal& set day=%result:~0,4%%separator%%result:~4,2%%separator%%result:~6,2%
echo %%day%% is set to "%day%" (without the quotes)
pause

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 08:24
by Aacini
@forumwurm: Perhaps would be better if you explain what you want to achieve :wink:

However, if you want the MM/YYYY date of previous month, use this code:

Code: Select all

rem Separate current date in month-1 and year parts:
for /F "tokens=2,3 delims=/" %%a in ("%date%") do set /A month=1%%a - 101, year=%%b
rem Check if previous month belongs to previous year and adjust they
if %month% equ 0 set /A month=12, year-=1
rem Insert left zero if month have just one digit
if %month% lss 10 set month=0%month%

echo Previous month is: %month%/%year%

You must note that set /A month=%date:~3,2% - 1 mark an error if the month is 08 or 09 because numbers with a left zero are taken as written in octal base in SET /A command. The right command in this case is: set /A month=1%date:~3,2% - 101, that is, take 108 or 109 and subtract 101.

Antonio

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 11:11
by forumwurm
the goal is to have two variables:

month=05
year=2013

with this variables the rest of the script is creating folders and files with the year and month of the previous month

So, when I run this script today (June 2013) I want to write the folder:

Folder1_abc_201305
Folder9_xyz_201305

I will try now your script.

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 11:31
by forumwurm
Hi Antonio

Thank you very much. You saved my day ;)

there was just one issue. the delims sign is in my computer not "/" but "."

So, now it seems to work. Will do the test with January, but I'm pretty sure this will work too.

thanks again.

br, chris

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 13:07
by aGerman
Hi Chris,

perhaps a bit exaggerated in your case but you could use some functions from my collection that respect different month lenghts and leap years.

Code: Select all

@echo off &setlocal

echo  - subtract 1 year
set "var_inY=2000" &set "var_inM=02" &set "var_inD=29"
call :YearsAdd %var_inY% %var_inM% %var_inD% -1 var_outY var_outM var_outD
set var_
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo  - subtract 1 month
set "var_inY=2000" &set "var_inM=03" &set "var_inD=31"
call :MonthsAdd %var_inY% %var_inM% %var_inD% -1 var_outY var_outM var_outD
set var_
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo  - subtract 1 day
set "var_inY=2000" &set "var_inM=01" &set "var_inD=01"
call :DaysAdd %var_inY% %var_inM% %var_inD% -1 var_outY var_outM var_outD
set var_
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

pause
goto :eof


:YearsAdd ByVal_YearIn ByVal_MonthIn ByVal_DayIn ByVal_DeltaIn ByRef_YearOut ByRef_MonthOut ByRef_DayOut
setlocal EnableExtensions DisableDelayedExpansion
set /a "Year = %~1 + %~4, Month = 100%~2 %% 100, Day = 100%~3 %% 100"
set /a "MaxDOM = 30 + !(((Month & 9) + 6) %% 7) + !(Month ^ 2) * (!(Year %% 4) - !(Year %% 100) + !(Year %% 400) - 2)"
if %Day% gtr %MaxDOM% set /a "Day=MaxDOM"
set /a "Month = 10%Month%, Day = 10%Day%"
endlocal &set "%~5=%Year%" &set "%~6=%Month:~-2%" &set "%~7=%Day:~-2%" &goto:eof

:MonthsAdd ByVal_YearIn ByVal_MonthIn ByVal_DayIn ByVal_DeltaIn ByRef_YearOut ByRef_MonthOut ByRef_DayOut
setlocal EnableExtensions DisableDelayedExpansion
set /a "Year = %~1, Month = 100%~2 %% 100, Day = 100%~3 %% 100"
set /a "Year = (Year * 12 + Month + %~4 - 1) / 12, Month = (((Month + %~4) %% 12) + 11) %% 12 + 1"
set /a "MaxDOM = 30 + !(((Month & 9) + 6) %% 7) + !(Month ^ 2) * (!(Year %% 4) - !(Year %% 100) + !(Year %% 400) - 2)"
if %Day% gtr %MaxDOM% set /a "Day=MaxDOM"
set /a "Month = 10%Month%, Day = 10%Day%"
endlocal &set "%~5=%Year%" &set "%~6=%Month:~-2%" &set "%~7=%Day:~-2%" &goto:eof

:DaysAdd ByVal_YearIn ByVal_MonthIn ByVal_DayIn ByVal_DeltaIn ByRef_YearOut ByRef_MonthOut ByRef_DayOut
setlocal EnableExtensions
set /a "Year = %~1, Month = 100%~2 %% 100, Day = 100%~3 %% 100"
set /a "a = 14 - Month, a /= 12, b = Year + 4800 - a, c = Month + 12 * a - 3, d = 153 * c + 2"
set /a "d = d / 5 + Day + b * 365 + b / 4 - b / 100 + b / 400 - 1 + %~4"
set /a "e = 4 * d + 3, e /= 146097, f = -e * 146097, f /= 4, f += d"
set /a "g = 4 * f + 3, g /= 1461, h = -1461 * g, h /= 4, h += f, i = 5 * h + 2, i /= 153, Day = 153 * i + 2, Day /= 5"
set /a "Day = -Day + h + 1, Month = -i / 10, Month *= 12, Month += i + 3, Year = e * 100 + g - 4800 + i / 10"
set /a "Month = 10%Month%, Day = 10%Day%"
endlocal &set "%~5=%Year%" &set "%~6=%Month:~-2%" &set "%~7=%Day:~-2%" &goto:eof


Regards
aGerman

Re: set variable 2012 (currentyear - 1)

Posted: 08 Jun 2013 17:48
by Aacini
@aGerman,

I tried your program and have a comment on one point. In :YearsAdd and :MonthsAdd routines, when the resulting date have a day that exceed month's days, your code eliminate days in excess and insert the last day of the resulting month (preserve month). However, there is a different way to obtain the result if we pay attention to the number of days instead. For example, if the calculation method indicate that the resulting date is 1 day after February/28, but February have just 28 days that year, then the right answer should be March/1. Isn't it? In a similar way than DaysAdd routine...

The Batch file below use this approach to calculate resulting dates. It have just one conversion routine that allows to insert increments for year, month or day, or any combination of the three.

Code: Select all

@echo off
setlocal

echo Subtract 1 year:
echo 2000/02/29
echo   -1/ 0/ 0
call :DateDelta 2000/02/29 -1/0/0
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo Subtract 1 month:
echo 2000/02/29
echo    0/-1/ 0
call :DateDelta 2000/02/29 0/-1/0 result=
echo %result%
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo Subtract 1 day:
echo 2000/01/01
echo    0/ 0/-1
call :DateDelta 2000/01/1 0/0/-1
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo What date will be the next year plus 2 months 15 days from today (2013/06/08)?
call :DateDelta 2013/06/08 1/2/15
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo And the same date, but 2 years ago?
call :DateDelta 2013/06/08 -2/2/15
goto :EOF


rem Both date and dateDelta must be given in Y/M/D order
rem DateDelta must have 3 numbers, each one with an optional negative sign

:DateDelta dateIn dateDelta [dateOut=]
setlocal
for /F "tokens=1-3 delims=/" %%a in ("%1") do (
   for /F "tokens=1-3 delims=/" %%d in ("%2") do (
      set /A "yy=%%a+%%d, mm=10%%b%%100+%%e, dd=10%%c%%100, a=(mm-14)/12"
      set /A "jdn=(1461*(yy+4800+a))/4+(367*(mm-2-12*a))/12-(3*((yy+4900+a)/100))/4+dd-32075+%%f"
   )
)
set /A l=jdn+68569,n=(4*l)/146097,l=l-(146097*n+3)/4,i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31
set /A j=(80*l)/2447,dd=100+l-(2447*j)/80,l=j/11,mm=100+j+2-(12*l),yy=100*(n-49)+i+l
set result=%yy%/%mm:~-2%/%dd:~-2%
endlocal & if "%3" neq "" (set "%3=%result%") else echo %result%
exit /B


Antonio

Re: set variable 2012 (currentyear - 1)

Posted: 09 Jun 2013 04:56
by aGerman
Hi Antonio,

there are different possible interpretations of how the result should look like. I picked up examples that make clear how my implementation works. It follows the VBScript built-in function "DateAdd" which works the same way. The reason is that this definition is very easy to understand. If adding 1 month I expect to get the next month. If adding 1 year I expect to get the same month next year. Of course that's just my thinking and other implementations should be right as well. Nothing but a question of how you define it :wink:

Regards
aGerman

Re: set variable 2012 (currentyear - 1)

Posted: 09 Jun 2013 20:23
by Aacini
Right, I see your point now:

VBScript built-in function DateAdd wrote:The DateAdd function won't return an invalid date. The following example adds one month to January 31:

Code: Select all

NewDate = DateAdd("m", 1, "31-Jan-95")

In this case, DateAdd returns 28-Feb-95, not 31-Feb-95. If date is 31-Jan-96, it returns 29-Feb-96 because 1996 is a leap year.


I modified my program to return dates in the same way of DateAdd function. Here it is:

Code: Select all

@echo off
setlocal

echo Subtract 1 year:
echo 2000/02/29
echo   -1/ 0/ 0
call :DateDelta 2000/02/29 -1/0/0
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo Subtract 1 month:
echo 2000/03/31
echo    0/-1/ 0
call :DateDelta 2000/03/31 0/-1/0 result=
echo %result%
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo Subtract 1 day:
echo 2000/01/01
echo    0/ 0/-1
call :DateDelta 2000/01/1 0/0/-1
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo What date will be the next year plus 1 month 10 days from 2013/01/19?
echo 2013/01/19
echo    1/ 1/10
call :DateDelta 2013/01/19 1/1/10
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

echo And the same date, but 1 year earlier?
echo 2013/01/19
echo   -1/ 1/10
call :DateDelta 2013/01/19 -1/1/10
goto :EOF


rem Both date and dateDelta must be given in Y/M/D order
rem dateDelta must have 3 numbers, each one with an optional negative sign

:DateDelta dateIn dateDelta [dateOut=]
setlocal EnableDelayedExpansion
for /F "tokens=1-3 delims=/" %%a in ("%1") do (
   for /F "tokens=1-3 delims=/" %%d in ("%2") do (
      set /A "yy=%%a+%%d+%%e/12, mmIn=(10%%b%%100+%%e-1)%%12+1, mmX2=(mmIn-1)*2, dd=10%%c%%100+(ddDelta=%%f)"
   )
)
set /A a=(mmIn-14)/12, jdn=(1461*(yy+4800+a))/4+(367*(mmIn-2-12*a))/12-(3*((yy+4900+a)/100))/4+dd-32075
set /A l=jdn+68569,n=(4*l)/146097,l=l-(146097*n+3)/4,i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31
set /A j=(80*l)/2447,dd=l-(2447*j)/80,l=j/11,mm=j+2-(12*l),yy=100*(n-49)+i+l,yyMOD4=yy%%4
if %ddDelta% equ 0 if %mm% neq %mmIn% (
   set DPM=312831303130313130313031
   if %yyMOD4% equ 0 set DPM=!DPM:8=9!
   set /A mm=mmIn, dd=!DPM:~%mmX2%,2!
)
set /A mm+=100, dd+=100   
set result=%yy%/%mm:~-2%/%dd:~-2%
endlocal & if "%3" neq "" (set "%3=%result%") else echo %result%
exit /B


Antonio

Re: set variable 2012 (currentyear - 1)

Posted: 10 Jun 2013 10:50
by aGerman
Yeah, thats a nice function :)