Adding Dates In DOS

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Muhnamana
Posts: 7
Joined: 31 May 2011 08:28

Adding Dates In DOS

#1 Post by Muhnamana » 31 May 2011 09:09

I have a lot of batch files were I prompt a user to enter a mail date by using the following command:

Code: Select all

@ech off
echo *********************************************
echo * Enter the maildate:                                                   *
echo * (See email for the maildate and format as MM/DD/YYYY)  *
echo *********************************************
SET /P MAIL_DATE=


This date that they enter, will always be a Monday date. I need to figure out how to add to this date to retrieve the Tuesday, Wednesday, Thursday and Friday dates, without having the user enter each date seperately.

Any help or suggestions would be appreciated!

Thanks!

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

Re: Adding Dates In DOS

#2 Post by dbenham » 31 May 2011 09:51

Step 1) use FOR /F "tokens=1-3 delims=/" to parse the date into component parts- MM, DD, YYYY. You could use substring operations but users may not including leading zeros for months and days, so that would be unreliable.

Step 2) Use www.dostips.com :date2jdate function to convert date into a Joulian date.

Step 3) Simply add (SET /A) 1 to get Tuesday, 2 for Wednesday, etc.

Step 4) Use :jdate2date function to convert the result back into a normal (Gregorian) date format.

Dave Benham

Muhnamana
Posts: 7
Joined: 31 May 2011 08:28

Re: Adding Dates In DOS

#3 Post by Muhnamana » 31 May 2011 11:41

Thanks for the reply dbenham.

I'm by now far an expert at this. All this is pretty much new to me.

So here's my current code, am I'm not sure why I'm not getting the correct julian date for 20110531.

Code: Select all

@echo off

echo **********************************************************
echo * Enter the Monday maildate:                             *
echo * (Format as YYYYMMDD) i.e. 20110531                     *
echo **********************************************************
SET /P MAIL_DATE=
SET MM=%MAIL_DATE:~6,2%
SET DD=%MAIL_DATE:~3,2%
SET YYYY=%MAIL_DATE:~0,4%

echo Converting Gregorian to Julian date...
:date2jdate JD YYYY MM DD -- converts a gregorian calender date to julian day format
::                        -- JD   [out] - julian days
::                        -- YYYY [in]  - gregorian year, i.e. 2006
::                        -- MM   [in]  - gregorian month, i.e. 12 for december
::                        -- DD   [in]  - gregorian day, i.e. 31
:$reference http://aa.usno.navy.mil/faq/docs/JD_Formula.html
:$created 20060101 :$changed 20080219 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL
set "yy=%~2"&set "mm=%~3"&set "dd=%~4"
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
if %yy% LSS 100 set /a yy+=2000 &rem Adds 2000 to two digit years
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
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
EXIT /b
echo Converting Gregorian to Julian date...Complete!

echo Converting to Julian to Gregorian date...
:jdate2date JD YYYY MM DD -- converts julian days to gregorian date format
::                     -- JD   [in]  - julian days
::                     -- YYYY [out] - gregorian year, i.e. 2006
::                     -- MM   [out] - gregorian month, i.e. 12 for december
::                     -- DD   [out] - gregorian day, i.e. 31
:$reference http://aa.usno.navy.mil/faq/docs/JD_Formula.html
:$created 20060101 :$changed 20080219 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set /a L= %~1+68569,     N= 4*L/146097, L= L-(146097*N+3)/4, I= 4000*(L+1)/1461001
set /a L= L-1461*I/4+31, J= 80*L/2447,  K= L-2447*J/80,      L= J/11
set /a J= J+2-12*L,      I= 100*(N-49)+I+L
set /a YYYY= I,  MM=100+J,  DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
( ENDLOCAL & REM RETURN VALUES
    IF "%~2" NEQ "" (SET %~2=%YYYY%) ELSE echo.%YYYY%
    IF "%~3" NEQ "" (SET %~3=%MM%) ELSE echo.%MM%
    IF "%~4" NEQ "" (SET %~4=%DD%) ELSE echo.%DD%
)
EXIT /b
echo Converting to Julian to Gregorian date...Complete!
pause

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

Re: Adding Dates In DOS

#4 Post by dbenham » 31 May 2011 15:38

Oh my, you are new to this! Welcome to the world of Windows batch programming :)

Those functions I referred you to are just that. They are functions that must be called using the CALL command. You should read this DOS Batch - Function Tutorial for general info about functions. The DOS tips web site demonstrates sophisticated batch programming techniques that you will not see in the average script! Don't worry if some of it doesn't make sense yet.

One of your best friends when learning batch programming (besides the DOS Tips site) will be the HELP command issued from an interactive command prompt. Learn how to use it.

In the mean time, here is a functioning program that demonstrates how to use the date functions.

Notes:
I reverted the entered date format to your original spec to demonstrate how to use the FOR /F command to parse the values.

Tuesday computation: I used the SET /A command to add 1 to the Monday Julian date.

Wednesday computation: I let the :jdate2date function perform the addition! This is not normal behavior of functions. It only works because the :jdate2date function is using SET /A when initially reading the argument.

Sunday computation: I added spaces to the simple math formula to show how you can include spaces in a function argument by enclosing the argument in quotes. I also printed the date directly without building a Sun variable.

After the last computation I added the EXIT /B to ensure that the code does not fall through and attempt to execute the functions without a call.

Code: Select all

@echo off
setlocal

SET /P "MAIL_DATE=Enter the Monday maildate (MM/DD/YYYY): "
for /f "tokens=1-3 delims=/" %%a in ("%MAIL_DATE%") do (
  set MonMM=%%a
  set MonDD=%%b
  set MonYYYY=%%c
)
echo Monday Date=%MAIL_DATE%
set mon
call :date2jdate MonJD %MonYYYY% %MonMM% %MonDD%
echo Julian date=%MonJD%

REM get Tuesday date
set /a TueJD=MonJD + 1
call :jdate2date TueJD TueYYYY TueMM TueDD
set Tue=%TueMM%/%TueDD%/%TueYYYY%
echo Following Tue=%Tue%

REM get Wednesday date
call :jdate2date (MonJD+2) WedYYYY WedMM WedDD
set Wed=%WedMM%/%WedDD%/%WedYYYY%
echo Following Wed=%Wed%

REM get Sunday date
call :jdate2date "(MonJD + 6)" SunYYYY SunMM SunDD
echo Following Sun=%SunMM%/%SunDD%/%SunYYYY%

pause

exit /b

:date2jdate JD YYYY MM DD -- converts a gregorian calender date to julian day format
::                        -- JD   [out] - julian days
::                        -- YYYY [in]  - gregorian year, i.e. 2006
::                        -- MM   [in]  - gregorian month, i.e. 12 for december
::                        -- DD   [in]  - gregorian day, i.e. 31
:$reference http://aa.usno.navy.mil/faq/docs/JD_Formula.html
:$created 20060101 :$changed 20080219 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL
set "yy=%~2"&set "mm=%~3"&set "dd=%~4"
set /a "yy=10000%yy% %%10000,mm=100%mm% %% 100,dd=100%dd% %% 100"
if %yy% LSS 100 set /a yy+=2000 &rem Adds 2000 to two digit years
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
ENDLOCAL & IF "%~1" NEQ "" (SET %~1=%JD%) ELSE (echo.%JD%)
EXIT /b

:jdate2date JD YYYY MM DD -- converts julian days to gregorian date format
::                     -- JD   [in]  - julian days
::                     -- YYYY [out] - gregorian year, i.e. 2006
::                     -- MM   [out] - gregorian month, i.e. 12 for december
::                     -- DD   [out] - gregorian day, i.e. 31
:$reference http://aa.usno.navy.mil/faq/docs/JD_Formula.html
:$created 20060101 :$changed 20080219 :$categories DateAndTime
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set /a L= %~1+68569,     N= 4*L/146097, L= L-(146097*N+3)/4, I= 4000*(L+1)/1461001
set /a L= L-1461*I/4+31, J= 80*L/2447,  K= L-2447*J/80,      L= J/11
set /a J= J+2-12*L,      I= 100*(N-49)+I+L
set /a YYYY= I,  MM=100+J,  DD=100+K
set MM=%MM:~-2%
set DD=%DD:~-2%
( ENDLOCAL & REM RETURN VALUES
    IF "%~2" NEQ "" (SET %~2=%YYYY%) ELSE echo.%YYYY%
    IF "%~3" NEQ "" (SET %~3=%MM%) ELSE echo.%MM%
    IF "%~4" NEQ "" (SET %~4=%DD%) ELSE echo.%DD%
)
EXIT /b

Sample output

Code: Select all

Enter the Monday maildate (MM/DD/YYYY): 5/30/2011
Monday Date=5/30/2011
MonDD=30
MonMM=5
MonYYYY=2011
Julian date=2455712
Following Tue=05/31/2011
Following Wed=06/01/2011
Following Sun=06/05/2011
Press any key to continue . . .


Addendum - you can validate the MAILDATE is a Monday by using the modulo (%) operator. Julian date modulo 7 = 0 for Monday, 1 for Tuesday, etc.

Code: Select all

set /a DayOfWeek=MonJD %% 7



Dave Benham

Muhnamana
Posts: 7
Joined: 31 May 2011 08:28

Re: Adding Dates In DOS

#5 Post by Muhnamana » 01 Jun 2011 06:55

Yeah this seems more advanced that the game I play...hahaha!

I just starting DOS programming not too long ago, seems like the best bet to do simple (maybe some complex) routines.

I'll definitely take a look at what you posted and see what I can figure out.

I appreciate the help you've given.

Muhnamana
Posts: 7
Joined: 31 May 2011 08:28

Re: Adding Dates In DOS

#6 Post by Muhnamana » 02 Jun 2011 07:11

Where exactly am I putting the addendum you mentioned? My guess would've been outside of the actual function but that didn't seem to work.

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

Re: Adding Dates In DOS

#7 Post by dbenham » 02 Jun 2011 15:13

I just rearranged the top of the code a bit and added a few lines: After computing the Julian date check if the modulo 7 = 0. If not then loop back and try again.

Code: Select all

:getMailDate
SET /P "MAIL_DATE=Enter the Monday maildate (MM/DD/YYYY): "
for /f "tokens=1-3 delims=/" %%a in ("%MAIL_DATE%") do (
  set MonMM=%%a
  set MonDD=%%b
  set MonYYYY=%%c
)
call :date2jdate MonJD %MonYYYY% %MonMM% %MonDD%
set /a dayOfWeek=monJD%%7
if not %dayOfWeek%==0 (
  echo:
  echo ERROR: That was not a Monday date! Try again.
  goto :getMailDate
)
echo Monday Date=%MAIL_DATE%
echo Julian date=%MonJD%


Dave

Post Reply