set variable 2012 (currentyear - 1)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
forumwurm
Posts: 4
Joined: 07 Jun 2013 15:25

set variable 2012 (currentyear - 1)

#1 Post by forumwurm » 07 Jun 2013 15:33

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

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

Re: set variable 2012 (currentyear - 1)

#2 Post by Acy Forsythe » 07 Jun 2013 15:55

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


Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set variable 2012 (currentyear - 1)

#3 Post by Aacini » 07 Jun 2013 19:41

Code: Select all

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

forumwurm
Posts: 4
Joined: 07 Jun 2013 15:25

Re: set variable 2012 (currentyear - 1)

#4 Post by forumwurm » 08 Jun 2013 01:19

@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%)

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: set variable 2012 (currentyear - 1)

#5 Post by foxidrive » 08 Jun 2013 03:20

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

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set variable 2012 (currentyear - 1)

#6 Post by Aacini » 08 Jun 2013 08:24

@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

forumwurm
Posts: 4
Joined: 07 Jun 2013 15:25

Re: set variable 2012 (currentyear - 1)

#7 Post by forumwurm » 08 Jun 2013 11:11

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.

forumwurm
Posts: 4
Joined: 07 Jun 2013 15:25

Re: set variable 2012 (currentyear - 1)

#8 Post by forumwurm » 08 Jun 2013 11:31

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

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: set variable 2012 (currentyear - 1)

#9 Post by aGerman » 08 Jun 2013 13:07

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

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set variable 2012 (currentyear - 1)

#10 Post by Aacini » 08 Jun 2013 17:48

@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

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: set variable 2012 (currentyear - 1)

#11 Post by aGerman » 09 Jun 2013 04:56

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

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set variable 2012 (currentyear - 1)

#12 Post by Aacini » 09 Jun 2013 20:23

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
Last edited by Aacini on 10 Jun 2013 10:59, edited 1 time in total.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: set variable 2012 (currentyear - 1)

#13 Post by aGerman » 10 Jun 2013 10:50

Yeah, thats a nice function :)

Post Reply