Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for datediff.bat

(view source code of datediff.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 ENABLEDELAYEDEXPANSION
  7.  
  8. :: Check the number of command line arguments
  9. IF     "%~1"=="" GOTO Syntax
  10. IF NOT "%~7"=="" GOTO Syntax
  11.  
  12. :: Initialize variables
  13. SET Date1=
  14. SET Date2=
  15. SET iDate=
  16. SET sDate=
  17. FOR /F "skip=1 tokens=2*" %%A IN ('REG.EXE Query "HKCU\Control Panel\International" /v iDate') DO SET iDateLocal=%%~B
  18. FOR /F "skip=1 tokens=2*" %%A IN ('REG.EXE Query "HKCU\Control Panel\International" /v sDate') DO SET sDateLocal=%%~B
  19. FOR %%A IN (%Date%) DO SET Today=%%A
  20. SET Verbose=0
  21. SET Debug=0
  22. TYPE "%~f0" | FINDSTR.EXE /R /B /I /C:":: *@ECHO OFF" >NUL && SET Debug=1
  23.  
  24. :: parse command line
  25. FOR %%A IN (%*) DO (
  26. 	SET Arg=%%~A
  27. 	IF "%Debug%"=="1" ECHO Arg=%%~A
  28. 	IF "!Arg:~0,1!"=="/" (
  29. 		IF /I "!Arg:~0,2!"=="/I" (
  30. 			IF "!iDate!"=="" (
  31. 				SET iDate=!Arg:~3!
  32. 				IF "%Debug%"=="1" ECHO iDate=!iDate!
  33. 				IF "%Debug%"=="1" ECHO iDateLocal=%iDateLocal%
  34. 			) ELSE (
  35. 				ECHO Duplicate switch /i
  36. 				ECHO.
  37. 				GOTO Syntax
  38. 			)
  39. 		) ELSE (
  40. 			IF /I "!Arg:~0,2!"=="/S" (
  41. 				IF "!sDate!"=="" (
  42. 					SET sDate=!Arg:~3!
  43. 					IF "%Debug%"=="1" ECHO sDate=!sDate!
  44. 				) ELSE (
  45. 					ECHO Duplicate switch /s
  46. 					ECHO.
  47. 					GOTO Syntax
  48. 				)
  49. 			) ELSE (
  50. 				IF /I "!Arg!"=="/V" (
  51. 					IF "!Verbose!"=="0" (
  52. 						SET Verbose=1
  53. 						IF "%Debug%"=="1" SET Verbose
  54. 					) ELSE (
  55. 						ECHO Duplicate switch /v
  56. 						ECHO.
  57. 						GOTO Syntax
  58. 					)
  59. 				) ELSE (
  60. 					IF /I "!Arg:~0,2!"=="/D" (
  61. 						SET Debug=1
  62. 						SET Debug
  63. 					) ELSE (
  64. 						ECHO Invalid command line switch !Arg!
  65. 						ECHO.
  66. 						GOTO Syntax
  67. 					)
  68. 				)
  69. 			)
  70. 		)
  71. 	) ELSE (
  72. 		IF "!Date1!"=="" (
  73. 			SET Date1=%%A
  74. 			IF "%Debug%"=="1" SET Date1
  75. 		) ELSE (
  76. 			IF "!Date2!"=="" (
  77. 				SET Date2=%%A
  78. 				IF "%Debug%"=="1" SET Date2
  79. 			) ELSE (
  80. 				ECHO Too many dates on command line
  81. 				ECHO.
  82. 				GOTO Syntax
  83. 			)
  84. 		)
  85. 	)
  86. )
  87.  
  88. SET iDateEnum.0=Month%sDate%Day%sDate%Year
  89. SET iDateEnum.1=Day%sDate%Month%sDate%Year
  90. SET iDateEnum.2=Year%sDate%Month%sDate%Day
  91.  
  92. :: Use today for second date if not spedified
  93. IF "%Date2%"=="" (
  94. 	IF %Debug%%Verbose% GEQ 1 SET Today
  95. 	IF %Debug%%Verbose% GEQ 1 SET Date2
  96. 	IF NOT "%iDate%%sDate%"=="" (
  97. 		CALL :ParseDate %Today% %iDateLocal% %sDateLocal%
  98. 		IF %iDate%==0 SET Today=!GMonth!%sDate%!GDay!%sDate%!GYear!
  99. 		IF %iDate%==1 SET Today=!GDay!%sDate%!GMonth!%sDate%!GYear!
  100. 		IF %iDate%==2 SET Today=!GYear!%sDate%!GMonth!%sDate%!GDay!
  101. 	)
  102. 	SET Date2=!Today!
  103. 	IF %Debug%%Verbose% GEQ 1 SET Today
  104. 	IF %Debug%%Verbose% GEQ 1 SET Date2
  105. )
  106.  
  107. :: Use local date format if no alternative was specified
  108. IF "%iDate%"=="" SET iDate=%iDateLocal%
  109. IF "%sDate%"=="" SET sDate=%sDateLocal%
  110.  
  111. IF "%verbose%"=="1" (
  112. 	ECHO Date format used:
  113. 	ECHO iDate=%iDate% ^(!iDateEnum.%iDate%!^)
  114. 	SET Local_iDate=!iDateEnum.%iDateLocal%!
  115. 	SET Local_iDate=!Local_iDate:%sDate%=%sDateLocal%!
  116. 	ECHO iDateLocal=%iDateLocal% ^(!Local_iDate!^)
  117. 	SET sDate
  118. 	ECHO.
  119. )
  120.  
  121. :: Check if the first date is valid
  122. (ECHO.%Date1%) | FINDSTR /R /B /C:"[0-9]*%sDate%[0-9]*%sDate%[0-9]*" >NUL
  123. IF ERRORLEVEL 1 (
  124. 	ECHO Error: %Date1% is not a valid date
  125. 	ECHO.
  126. 	GOTO Syntax
  127. )
  128.  
  129. :: Check if the second date is valid
  130. (ECHO.%Date2%) | FINDSTR /R /B /C:"[0-9]*%sDate%[0-9]*%sDate%[0-9]*" >NUL
  131. IF ERRORLEVEL 1 (
  132. 	ECHO Error: %Date2% is not a valid date
  133. 	ECHO.
  134. 	GOTO Syntax
  135. )
  136.  
  137. :: Parse the first date
  138. CALL :ParseDate %Date1%
  139. IF "%Verbose%"=="1" (
  140. 	ECHO Date1=%Date1%
  141. 	SET GYear
  142. 	SET GMonth
  143. 	SET GDay
  144. 	ECHO.
  145. )
  146. IF %GDay% GTR 31 (
  147. 	ECHO Invalid date, day cannot be greater than 31
  148. 	ECHO.
  149. 	GOTO Syntax
  150. )
  151. IF %GMonth% GTR 12 (
  152. 	ECHO Invalid date, month cannot be greater than 12
  153. 	ECHO.
  154. 	GOTO Syntax
  155. )
  156.  
  157. :: Convert the parsed Gregorian date to Julian
  158. CALL :JDate %GYear% %GMonth% %GDay%
  159. IF "%Verbose%"=="1" (
  160. 	ECHO Julian Date1
  161. 	SET JDate
  162. 	ECHO.
  163. )
  164.  
  165. :: Save the resulting Julian date
  166. SET JDate1=%JDate%
  167.  
  168. :: Parse the second date
  169. CALL :ParseDate %Date2%
  170. IF "%Verbose%"=="1" (
  171. 	ECHO Date2=%Date2%
  172. 	SET GYear
  173. 	SET GMonth
  174. 	SET GDay
  175. 	ECHO.
  176. )
  177. IF %GDay% GTR 31 (
  178. 	ECHO Invalid date, day cannot be greater than 31
  179. 	ECHO.
  180. 	GOTO Syntax
  181. )
  182. IF %GMonth% GTR 12 (
  183. 	ECHO Invalid date, month cannot be greater than 12
  184. 	ECHO.
  185. 	GOTO Syntax
  186. )
  187.  
  188. :: Convert the parsed Gregorian date to Julian
  189. CALL :JDate %GYear% %GMonth% %GDay%
  190. IF "%Verbose%"=="1" (
  191. 	ECHO Julian Date2
  192. 	SET JDate
  193. 	ECHO.
  194. )
  195.  
  196. :: Calculate the absolute value of the difference in days
  197. IF %JDate% GTR %JDate1% (
  198. 	SET /A DateDiff = %JDate% - %JDate1%
  199. ) ELSE (
  200. 	SET /A DateDiff = %JDate1% - %JDate%
  201. )
  202.  
  203. :: Format output for singular or plural
  204. SET Days=days
  205. IF %DateDiff% EQU 1 SET Days=day
  206.  
  207. :: Prefix value with a minus sign if negative
  208. IF %JDate% GTR %JDate1% SET DateDiff=-%DateDiff%
  209.  
  210. :: Display the result
  211. ECHO First date  : %Date1%
  212. ECHO Second date : %Date2%
  213. ECHO Difference  : %DateDiff% %Days%
  214.  
  215. :: Return the result in a variable named after this batch file
  216. ENDLOCAL & SET %~n0=%DateDiff%
  217. GOTO:EOF
  218.  
  219.  
  220. ::===================================::
  221. ::                                   ::
  222. ::   -   S u b r o u t i n e s   -   ::
  223. ::                                   ::
  224. ::===================================::
  225.  
  226.  
  227. :JDate
  228. :: Convert date to Julian
  229. :: Arguments : YYYY MM DD
  230. :: Returns   : Julian date
  231. ::
  232. :: First strip 1 or 2 leading zeroes; a logical error in this
  233. :: routine was corrected with help from Alexander Shapiro
  234. SET MM=%2
  235. SET DD=%3
  236. IF "%MM:~0,1%"=="0" IF NOT "%MM%"=="0" SET MM=%MM:~1%
  237. IF "%MM:~0,1%"=="0" IF NOT "%MM%"=="0" SET MM=%MM:~1%
  238. IF "%DD:~0,1%"=="0" IF NOT "%DD%"=="0" SET DD=%DD:~1%
  239. IF "%DD:~0,1%"=="0" IF NOT "%DD%"=="0" SET DD=%DD:~1%
  240. ::
  241. :: Algorithm based on Fliegel-Van Flandern
  242. :: algorithm from the Astronomical Almanac,
  243. :: provided by Doctor Fenton on the Math Forum
  244. :: (http://mathforum.org/library/drmath/view/51907.html),
  245. :: and converted to batch code by Ron Bakowski.
  246. SET /A Month1 = ( %MM% - 14 ) / 12
  247. SET /A Year1  = %1 + 4800
  248. SET /A JDate  = 1461 * ( %Year1% + %Month1% ) / 4 + 367 * ( %MM% - 2 -12 * %Month1% ) / 12 - ( 3 * ( ( %Year1% + %Month1% + 100 ) / 100 ) ) / 4 + %DD% - 32075
  249. FOR %%A IN (Month1 Year1) DO SET %%A=
  250. GOTO:EOF 
  251.  
  252.  
  253. :ParseDate
  254. :: Parse (Gregorian) date depending on registry's date format settings
  255. :: Argument : Gregorian date in local date format, optional iDate and sDate alternatives (in that order)
  256. :: Requires : sDate (local date separator), iDate (local date format number)
  257. :: Returns  : GYear (4-digit year), GMonth (2-digit month), GDay (2-digit day)
  258. ::
  259. SET iDateUsed=%iDate%
  260. SET sDateUsed=%sDate%
  261. IF NOT "%~2"=="" SET iDateUsed=%~2
  262. IF NOT "%~3"=="" SET sDateUsed=%~3
  263. IF %iDateUsed%==0 FOR /F "TOKENS=1-3 DELIMS=%sDateUsed%" %%A IN ("%~1") DO (
  264. 	SET GYear=%%~C
  265. 	SET GMonth=%%~A
  266. 	SET GDay=%%~B
  267. )
  268. IF %iDateUsed%==1 FOR /F "TOKENS=1-3 DELIMS=%sDateUsed%" %%A IN ("%~1") DO (
  269. 	SET GYear=%%~C
  270. 	SET GMonth=%%~B
  271. 	SET GDay=%%~A
  272. )
  273. IF %iDateUsed%==2 FOR /F "TOKENS=1-3 DELIMS=%sDateUsed%" %%A IN ("%~1") DO (
  274. 	SET GYear=%%~A
  275. 	SET GMonth=%%~B
  276. 	SET GDay=%%~C
  277. )
  278. SET iDateUsed=
  279. SET sDateUsed=
  280. GOTO:EOF
  281.  
  282.  
  283. :Syntax
  284. ECHO DateDiff.bat,  Version 1.11 for Windows XP .. 10
  285. ECHO Calculate the difference (in days) between two dates
  286. ECHO.
  287. ECHO Usage:  DATEDIFF  date  [ date  [ /i:iDate ]  [ /s:sDate ] ]  [ /v ]
  288. ECHO.
  289. ECHO Where:  "date"    is a "normal" Gregorian date in the computer's
  290. ECHO                   local format; if no second date is specified,
  291. ECHO                   today is assumed
  292. ECHO         /i:iDate  specify alternative date format:
  293. ECHO                   iDate = 0 for month/day/year format
  294. ECHO                   iDate = 1 for day/month/year format
  295. ECHO                   iDate = 2 for year/month/day format
  296. ECHO         /s:sDate  specify alternative date separator
  297. ECHO                   (/ or - or . or whatever you want)
  298. ECHO         /v        Verbose output
  299. ECHO.
  300. ECHO Julian date conversion based on Fliegel-Van Flandern algorithms from
  301. ECHO the Astronomical Almanac, provided by Doctor Fenton on the Math Forum
  302. ECHO (http://mathforum.org/library/drmath/view/51907.html), and converted
  303. ECHO to batch code by Ron Bakowski.
  304. ECHO Bug found by and corrected with help from Alexander Shapiro.
  305. ECHO.
  306. ECHO Written by Rob van der Woude
  307. ECHO http://www.robvanderwoude.com
  308.  
  309. IF "%OS%"=="Windows_NT" ENDLOCAL
  310. EXIT /B 1
  311.  

page last modified: 2024-04-16; loaded in 0.0223 seconds