Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for dateadd.bat

(view source code of dateadd.bat as plain text)

  1. @ECHO OFF
  2. ECHO.
  3.  
  4. :: Check the Windows version
  5. IF NOT "%OS%"=="Windows_NT" GOTO Syntax
  6. SETLOCAL
  7.  
  8. :: Initialize variable
  9. SET Error=0
  10.  
  11. :: Check the command line arguments
  12. IF     "%~1"=="" GOTO Syntax
  13. IF NOT "%~3"=="" GOTO Syntax
  14. IF "%~2"=="" (
  15. 	FOR %%A IN (%Date%) DO SET cDate=%%A
  16. 	SET cDays=%~1
  17. ) ELSE (
  18. 	SET cDate=%~1
  19. 	SET cDays=%~2
  20. )
  21.  
  22. :: Read the Date format from the registry
  23. CALL :ReadDateFormat
  24.  
  25. :: Check if a valid date was specified
  26. (ECHO.%cDate%) | FINDSTR /R /B /C:"[0-9]*\%sDate%[0-9]*\%sDate%[0-9]*" >NUL
  27. IF ERRORLEVEL 1 (
  28. 	ECHO Error: %cDate% is not a valid date
  29. 	ECHO.
  30. 	GOTO Syntax
  31. )
  32.  
  33. :: Check if the second argument is a valid number
  34. (ECHO.%cDays%) | FINDSTR /R /B /C:"-*[0-9]*" >NUL
  35. IF ERRORLEVEL 1 (
  36. 	ECHO Error: %cDays% is not an integer
  37. 	ECHO.
  38. 	GOTO Syntax
  39. )
  40.  
  41. :: Parse the date specified
  42. CALL :ParseDate %cDate%
  43.  
  44. :: Check for errors
  45. IF %Error% NEQ 0 GOTO Syntax
  46.  
  47. :: Convert the parsed Gregorian date to Julian
  48. CALL :JDate %GYear% %GMonth% %GDay%
  49.  
  50. :: Display original input
  51. ECHO Starting date   : %cDate%
  52.  
  53. :: Add or subtract the specified number of days
  54. IF "%cDays:~0,1%"=="-" (
  55. 	SET /A NewJDate = %JDate% - %cDays:~1%
  56. 	ECHO Days subtracted : %cDays:~1%
  57. ) ELSE (
  58. 	SET /A NewJDate = %JDate% + %cDays%
  59. 	ECHO Days added      : %cDays%
  60. )
  61.  
  62. :: Convert the new Julian date back to Gregorian again
  63. CALL :GDate %NewJDate%
  64.  
  65. :: Reformat the date to local format
  66. CALL :ReformatDate %GDate%
  67.  
  68. :: Display the result
  69. ECHO Resulting date  : %LDate%
  70.  
  71. :: Return the result in a variable named after this batch file
  72. ENDLOCAL & SET %~n0=%LDate%
  73. GOTO:EOF
  74.  
  75.  
  76. ::===================================::
  77. ::                                   ::
  78. ::   -   S u b r o u t i n e s   -   ::
  79. ::                                   ::
  80. ::===================================::
  81.  
  82.  
  83. :GDate
  84. :: Convert Julian date back to "normal" Gregorian date
  85. :: Argument : Julian date
  86. :: Returns  : YYYY MM DD
  87. ::
  88. :: Algorithm based on Fliegel-Van Flandern
  89. :: algorithm from the Astronomical Almanac,
  90. :: provided by Doctor Fenton on the Math Forum
  91. :: (http://mathforum.org/library/drmath/view/51907.html),
  92. :: and converted to batch code by Ron Bakowski.
  93. ::
  94. SET /A P      = %1 + 68569
  95. SET /A Q      = 4 * %P% / 146097
  96. SET /A R      = %P% - ( 146097 * %Q% +3 ) / 4
  97. SET /A S      = 4000 * ( %R% + 1 ) / 1461001
  98. SET /A T      = %R% - 1461 * %S% / 4 + 31
  99. SET /A U      = 80 * %T% / 2447
  100. SET /A V      = %U% / 11
  101. SET /A GYear  = 100 * ( %Q% - 49 ) + %S% + %V%
  102. SET /A GMonth = %U% + 2 - 12 * %V%
  103. SET /A GDay   = %T% - 2447 * %U% / 80
  104. :: Clean up the mess
  105. FOR %%A IN (P Q R S T U V) DO SET %%A=
  106. :: Add leading zeroes
  107. IF 1%GMonth% LSS 20 SET GMonth=0%GMonth%
  108. IF 1%GDay%   LSS 20 SET GDay=0%GDay%
  109. :: Return value
  110. SET GDate=%GYear% %GMonth% %GDay%
  111. GOTO:EOF
  112.  
  113.  
  114. :JDate
  115. :: Convert date to Julian
  116. :: Arguments : YYYY MM DD
  117. :: Returns   : Julian date
  118. ::
  119. :: First strip leading zeroes
  120. SET MM=%2
  121. SET DD=%3
  122. IF %MM:~0,1% EQU 0 SET MM=%MM:~1%
  123. IF %DD:~0,1% EQU 0 SET DD=%DD:~1%
  124. ::
  125. :: Algorithm based on Fliegel-Van Flandern
  126. :: algorithm from the Astronomical Almanac,
  127. :: provided by Doctor Fenton on the Math Forum
  128. :: (http://mathforum.org/library/drmath/view/51907.html),
  129. :: and converted to batch code by Ron Bakowski.
  130. SET /A Month1 = ( %MM% - 14 ) / 12
  131. SET /A Year1  = %1 + 4800
  132. SET /A JDate  = 1461 * ( %Year1% + %Month1% ) / 4 + 367 * ( %MM% - 2 -12 * %Month1% ) / 12 - ( 3 * ( ( %Year1% + %Month1% + 100 ) / 100 ) ) / 4 + %DD% - 32075
  133. FOR %%A IN (Month1 Year1) DO SET %%A=
  134. GOTO:EOF 
  135.  
  136.  
  137. :ParseDate
  138. :: Parse (Gregorian) date depending on registry's date format settings
  139. :: Argument : Gregorian date in local date format,
  140. :: Requires : sDate (local date separator), iDate (local date format number)
  141. :: Returns  : GYear (4-digit year), GMonth (2-digit month), GDay (2-digit day)
  142. ::
  143. IF %iDate%==0 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
  144. 	SET GYear=%%C
  145. 	SET GMonth=%%A
  146. 	SET GDay=%%B
  147. )
  148. IF %iDate%==1 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
  149. 	SET GYear=%%C
  150. 	SET GMonth=%%B
  151. 	SET GDay=%%A
  152. )
  153. IF %iDate%==2 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
  154. 	SET GYear=%%A
  155. 	SET GMonth=%%B
  156. 	SET GDay=%%C
  157. )
  158. IF %GDay%   GTR 31 SET Error=1
  159. IF %GMonth% GTR 12 SET Error=1
  160. GOTO:EOF
  161.  
  162.  
  163. :ReadDateFormat
  164. :: Read the Date format from the registry.
  165. :: Arguments : none
  166. :: Returns   : sDate (separator), iDate (date format number)
  167. ::
  168. :: First, export registry settings to a temporary file:
  169. START /W REGEDIT /E "%TEMP%.\_TEMP.REG" "HKEY_CURRENT_USER\Control Panel\International"
  170. :: Now, read the exported data:
  171. FOR /F "tokens=1* delims==" %%A IN ('TYPE "%TEMP%.\_TEMP.REG" ^| FIND /I "iDate"') DO SET iDate=%%B
  172. FOR /F "tokens=1* delims==" %%A IN ('TYPE "%TEMP%.\_TEMP.REG" ^| FIND /I "sDate"') DO SET sDate=%%B
  173. :: Remove the temporary file:
  174. DEL "%TEMP%.\_TEMP.REG"
  175. :: Remove quotes from the data read:
  176. :: SET iDate=%iDate:"=%
  177. FOR %%A IN (%iDate%) DO SET iDate=%%~A
  178. :: SET sDate=%sDate:"=%
  179. FOR %%A IN (%sDate%) DO SET sDate=%%~A
  180. GOTO:EOF
  181.  
  182.  
  183. :ReformatDate
  184. :: Reformat the date back to the local format
  185. :: Arguments : YYYY MM DD
  186. :: Returns   : LDate (Gregorian date in local format)
  187. ::
  188. IF %iDate%==0 SET LDate=%2%sDate%%3%sDate%%1
  189. IF %iDate%==1 SET LDate=%3%sDate%%2%sDate%%1
  190. IF %iDate%==2 SET LDate=%1%sDate%%2%sDate%%3
  191. GOTO:EOF
  192.  
  193.  
  194. :Syntax
  195. ECHO DateAdd.bat,  Version 1.10 for Windows NT 4 / 2000 / XP / Server 2003 / Vista
  196. ECHO Add (or subtract) the specified number of days to (or from) the specified date
  197. ECHO.
  198. ECHO Usage:  DATEADD  [ date ]  days
  199. ECHO.
  200. ECHO Where:  "date"   is a "normal" Gregorian date in the local computer's format
  201. ECHO                  (default value if no date is specified: today's date)
  202. ECHO         "days"   is the number of days to add or subtract
  203. ECHO.
  204. IF     "%OS%"=="Windows_NT" FOR %%A IN (%Date%) DO SET Today=%%A
  205. IF     "%OS%"=="Windows_NT" ECHO E.g.    DATEADD %Today%  1 will return tomorrow's date  (as will DATEADD  1)
  206. IF     "%OS%"=="Windows_NT" ECHO         DATEADD %Today% -1 will return yesterday's date (as will DATEADD -1)
  207. IF     "%OS%"=="Windows_NT" ENDLOCAL
  208. IF NOT "%OS%"=="Windows_NT" ECHO E.g.    DATEADD 01/25/2007  1 should return 01/26/2007
  209. IF NOT "%OS%"=="Windows_NT" ECHO         DATEADD 01/25/2007 -1 should return 01/24/2007
  210. ECHO.
  211. ECHO Julian date conversion based on Fliegel-Van Flandern algorithms from
  212. ECHO the Astronomical Almanac, provided by Doctor Fenton on the Math Forum
  213. ECHO (http://mathforum.org/library/drmath/view/51907.html), and converted
  214. ECHO to batch code by Ron Bakowski.
  215. ECHO.
  216. ECHO Written by Rob van der Woude
  217. ECHO http://www.robvanderwoude.com
  218.  

page last modified: 2024-02-26; loaded in 0.0276 seconds