Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for datediff.cs

(view source code of datediff.cs as plain text)

  1. using System;
  2. using System.Collections.Generic;
  3.  
  4.  
  5. namespace RobvanderWoude
  6. {
  7. 	class DateDiff
  8. 	{
  9. 		public static string progver = "1.02";
  10. 		static int rc = 1;
  11.  
  12.  
  13. 		static int Main( string[] args )
  14. 		{
  15. 			#region Initialize Variables
  16.  
  17. 			bool swdays = false;
  18. 			bool swhours = false;
  19. 			bool swmils = false;
  20. 			bool swmins = false;
  21. 			bool swraw = false;
  22. 			bool swsign = false;
  23. 			bool swsecs = false;
  24. 			bool swticks = false;
  25. 			bool swverbose = false;
  26. 			bool swweeks = false;
  27. 			bool swyears = false;
  28. 			DateTime dt1;
  29. 			DateTime dt2;
  30. 			int years = 0;
  31. 			string sign = String.Empty;
  32.  
  33. 			#endregion Initialize Variables
  34.  
  35.  
  36. 			#region Command Line Parsing
  37.  
  38. 			if ( args.Length < 2 || args.Length > 3 )
  39. 			{
  40. 				return ShowHelp( );
  41. 			}
  42.  
  43. 			foreach ( string arg in args )
  44. 			{
  45. 				if ( arg == "/?" )
  46. 				{
  47. 					return ShowHelp( );
  48. 				}
  49. 			}
  50.  
  51. 			try
  52. 			{
  53. 				if ( args[0].ToLower( ) == "now" )
  54. 				{
  55. 					dt1 = DateTime.Now;
  56. 				}
  57. 				else
  58. 				{
  59. 					dt1 = Convert.ToDateTime( args[0] );
  60. 				}
  61. 			}
  62. 			catch ( FormatException )
  63. 			{
  64. 				return ShowHelp( "Invalid date/time format \"{0}\"", args[0] );
  65. 			}
  66.  
  67. 			try
  68. 			{
  69. 				if ( args[1].ToLower( ) == "now" )
  70. 				{
  71. 					dt2 = DateTime.Now;
  72. 				}
  73. 				else
  74. 				{
  75. 					dt2 = Convert.ToDateTime( args[1] );
  76. 				}
  77. 			}
  78. 			catch ( FormatException )
  79. 			{
  80. 				return ShowHelp( "Invalid date/time format \"{0}\"", args[1] );
  81. 			}
  82.  
  83. 			if ( args.Length == 3 )
  84. 			{
  85. 				switch ( args[2].ToUpper( ) )
  86. 				{
  87. 					case "/A":
  88. 						rc = 1;
  89. 						swsign = true;
  90. 						break;
  91. 					case "/D":
  92. 						rc = 0;
  93. 						swdays = true;
  94. 						break;
  95. 					case "/H":
  96. 						rc = 0;
  97. 						swhours = true;
  98. 						break;
  99. 					case "/I":
  100. 						rc = 1;
  101. 						swmils = true;
  102. 						break;
  103. 					case "/M":
  104. 						rc = 0;
  105. 						swmins = true;
  106. 						break;
  107. 					case "/R":
  108. 						rc = 1;
  109. 						swraw = true;
  110. 						break;
  111. 					case "/S":
  112. 						rc = 0;
  113. 						swsecs = true;
  114. 						break;
  115. 					case "/T":
  116. 						rc = 1;
  117. 						swticks = true;
  118. 						break;
  119. 					case "/V":
  120. 						rc = 1;
  121. 						swverbose = true;
  122. 						break;
  123. 					case "/W":
  124. 						rc = 0;
  125. 						swweeks = true;
  126. 						break;
  127. 					case "/Y":
  128. 						rc = 0;
  129. 						swyears = true;
  130. 						break;
  131. 					default:
  132. 						rc = 1;
  133. 						return ShowHelp( "Invalid command line argument \"{0}\"", args[2] );
  134. 				}
  135. 			}
  136.  
  137. 			#endregion Command Line Parsing
  138.  
  139.  
  140. 			try
  141. 			{
  142. 				TimeSpan diff = dt1 - dt2;
  143.  
  144. 				if ( swraw )
  145. 				{
  146. 					Console.WriteLine( diff );
  147. 					return 0;
  148. 				}
  149.  
  150. 				if ( swticks )
  151. 				{
  152. 					Console.WriteLine( diff.Ticks );
  153. 					return 0;
  154. 				}
  155.  
  156. 				if ( swsign )
  157. 				{
  158. 					Console.WriteLine( ( diff.Ticks < 0 ? "-" : "+" ) );
  159. 					return 0;
  160. 				}
  161.  
  162. 				if ( diff.Ticks < 0 )
  163. 				{
  164. 					// swap command line arguments, required to separate the years from the days
  165. 					dt1 = Convert.ToDateTime( args[1] );
  166. 					dt2 = Convert.ToDateTime( args[0] );
  167. 					diff = dt1 - dt2;
  168. 					sign = "-";
  169. 				}
  170.  
  171. 				if ( args.Length == 3 && !swverbose && !swyears )
  172. 				{
  173. 					if ( swdays )
  174. 					{
  175. 						rc = diff.Days;
  176. 					}
  177. 					if ( swweeks )
  178. 					{
  179. 						rc = Convert.ToInt32( diff.Days / 7 );
  180. 					}
  181. 					if ( swhours )
  182. 					{
  183. 						rc = diff.Days * 24 + diff.Hours;
  184. 					}
  185. 					if ( swmins )
  186. 					{
  187. 						rc = ( diff.Days * 24 + diff.Hours ) * 60 + diff.Minutes;
  188. 					}
  189. 					if ( swsecs )
  190. 					{
  191. 						rc = Convert.ToInt32( diff.Ticks / 10000000 );
  192. 					}
  193. 					if ( swmils )
  194. 					{
  195. 						rc = Convert.ToInt32( diff.Ticks / 10000 );
  196. 					}
  197. 					Console.WriteLine( "{0}{1}", sign, rc );
  198. 					return rc;
  199. 				}
  200.  
  201. 				years = dt1.Year - dt2.Year;
  202. 				if ( years != 0 )
  203. 				{
  204. 					dt2 = dt2.AddYears( years );
  205. 					diff = dt1 - dt2;
  206. 				}
  207. 				if ( diff.Days < 0 )
  208. 				{
  209. 					dt2 = dt2.AddYears( -1 );
  210. 					diff = dt1 - dt2;
  211. 					years -= 1;
  212. 				}
  213.  
  214. 				if ( swyears )
  215. 				{
  216. 					Console.WriteLine( "{0}{1}", sign, years );
  217. 					return years;
  218. 				}
  219.  
  220. 				string result = String.Empty;
  221. 				if ( years != 0 || swverbose )
  222. 				{
  223. 					result += String.Format( "{0}{1} year{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), years, ( Math.Abs( years ) == 1 ? String.Empty : "s" ) );
  224. 				}
  225. 				if ( diff.Days != 0 || !String.IsNullOrEmpty( result ) || swverbose )
  226. 				{
  227. 					result += String.Format( "{0}{1} day{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), diff.Days, ( Math.Abs( diff.Days ) == 1 ? String.Empty : "s" ) );
  228. 				}
  229. 				if ( diff.Hours != 0 || !String.IsNullOrEmpty( result ) || swverbose )
  230. 				{
  231. 					result += String.Format( "{0}{1} hour{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), diff.Hours, ( Math.Abs( diff.Hours ) == 1 ? String.Empty : "s" ) );
  232. 				}
  233. 				if ( diff.Minutes != 0 || !String.IsNullOrEmpty( result ) || swverbose )
  234. 				{
  235. 					result += String.Format( "{0}{1} minute{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), diff.Minutes, ( Math.Abs( diff.Minutes ) == 1 ? String.Empty : "s" ) );
  236. 				}
  237. 				if ( diff.Seconds != 0 || !String.IsNullOrEmpty( result ) || swverbose )
  238. 				{
  239. 					result += String.Format( "{0}{1} second{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), diff.Seconds, ( Math.Abs( diff.Seconds ) == 1 ? String.Empty : "s" ) );
  240. 				}
  241. 				if ( diff.Milliseconds != 0 || swverbose )
  242. 				{
  243. 					result += String.Format( "{0}{1} millisecond{2}", ( String.IsNullOrEmpty( result ) ? String.Empty : ", " ), diff.Milliseconds, ( Math.Abs( diff.Milliseconds ) == 1 ? String.Empty : "s" ) );
  244. 				}
  245. 				Console.WriteLine( "{0}{1}{2}", sign, ( String.IsNullOrEmpty( sign ) ? String.Empty : " " ), result );
  246. 				return rc;
  247. 			}
  248. 			catch ( Exception e )
  249. 			{
  250. 				return ShowHelp( e.Message );
  251. 			}
  252. 		}
  253.  
  254.  
  255. 		#region Error handling
  256.  
  257. 		static int ShowHelp( params string[] errmsg )
  258. 		{
  259. 			/*
  260. 			DateDiff,  Version 1.02
  261. 			Batch tool calculate the timespan between two specified dates
  262.  
  263. 			Usage:    DATEDIFF  date  date  [ option ]
  264.  
  265. 			Where:    "date"    is a date/time in local or ISO date/time format, or "Now"
  266. 			          "option"  can be one of the following switches:
  267. 			                    /A    return only the sign of the timespan (+ or -)
  268. 			                    /D    return total number of entire Days in timespan
  269. 			                    /H    return total number of entire Hours in timespan
  270. 			                    /I    return total number of mIlliseconds in timespan
  271. 			                    /M    return total number of entire Minutes in timespan
  272. 			                    /R    return Raw timespan string (+/-dd.hh:mm:ss.iii000000)
  273. 			                    /S    return total number of entire Seconds in timespan
  274. 			                    /T    return total number of Ticks in timespan
  275. 			                    /V    Verbose output string, including leading and trailing
  276. 			                          zeroes (e.g. 0 years, or 0 milliseconds)
  277. 			                    /W    return total number of entire Weeks in timespan
  278. 			                    /Y    return number of entire Years in timespan
  279.  
  280. 			Notes:    Dates must be entered either in YYYY-MM-DD [hh:mm[:ss[.iii]]] format,
  281. 			          or in local system's date/time format with DOT for decimal delimiter,
  282. 			          or as "Now", in which case the current date and time will be used.
  283. 			          In both dates, date and time components are optional, but at least
  284. 			          one of these must be specified: if no date is specified, today is
  285. 			          assumed, if no time is specified, 00:00:00.000000000 is assumed.
  286. 			          Defaults output: years, days, hours, minutes, seconds, milliseconds;
  287. 			          first value shown will be first non-zero value, unless /V specified;
  288. 			          milliseconds will not be shown if zero, unless /V or /I specified.
  289. 			          Return code ("ErrorLevel") equals absolute value of the result for
  290. 			          /D or /H or /M or /S or /W or /Y switches; otherwise 0 if result is
  291. 			          valid or 1 in case of (command line) errors.
  292.  
  293. 			Written by Rob van der Woude
  294. 			http://www.robvanderwoude.com
  295. 			*/
  296.  
  297. 			if ( errmsg.Length > 0 )
  298. 			{
  299. 				List<string> errargs = new List<string>( errmsg );
  300. 				errargs.RemoveAt( 0 );
  301. 				Console.Error.WriteLine( );
  302. 				Console.ForegroundColor = ConsoleColor.Red;
  303. 				Console.Error.Write( "ERROR:\t" );
  304. 				Console.ForegroundColor = ConsoleColor.White;
  305. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  306. 				Console.ResetColor( );
  307.  
  308. 			}
  309.  
  310. 			Console.Error.WriteLine( );
  311. 			Console.Error.WriteLine( "DateDiff,  Version {0}", progver );
  312. 			Console.Error.WriteLine( "Batch tool calculate the timespan between two specified dates" );
  313. 			Console.Error.WriteLine( );
  314. 			Console.Error.Write( "Usage:    " );
  315. 			Console.ForegroundColor = ConsoleColor.White;
  316. 			Console.Error.WriteLine( "DATEDIFF  date  date  [ option ]" );
  317. 			Console.ResetColor( );
  318. 			Console.Error.WriteLine( );
  319.  
  320. 			Console.Error.Write( "Where:    " );
  321. 			Console.ForegroundColor = ConsoleColor.White;
  322. 			Console.Error.Write( "\"date\"" );
  323. 			Console.ResetColor( );
  324. 			Console.Error.WriteLine( "    is a date/time in local or ISO date/time format, or \"Now\"" );
  325.  
  326. 			Console.ForegroundColor = ConsoleColor.White;
  327. 			Console.Error.Write( "          \"option\"" );
  328. 			Console.ResetColor( );
  329. 			Console.Error.WriteLine( "  can be one of the following switches:" );
  330.  
  331. 			Console.ForegroundColor = ConsoleColor.White;
  332. 			Console.Error.Write( "                    /A" );
  333. 			Console.ResetColor( );
  334. 			Console.Error.WriteLine( "    return only the sign of the timespan (+ or -)" );
  335.  
  336. 			Console.ForegroundColor = ConsoleColor.White;
  337. 			Console.Error.Write( "                    /D" );
  338. 			Console.ResetColor( );
  339. 			Console.Error.Write( "    return total number of entire " );
  340. 			Console.ForegroundColor = ConsoleColor.White;
  341. 			Console.Error.Write( "D" );
  342. 			Console.ResetColor( );
  343. 			Console.Error.WriteLine( "ays in timespan" );
  344.  
  345. 			Console.ForegroundColor = ConsoleColor.White;
  346. 			Console.Error.Write( "                    /H" );
  347. 			Console.ResetColor( );
  348. 			Console.Error.Write( "    return total number of entire " );
  349. 			Console.ForegroundColor = ConsoleColor.White;
  350. 			Console.Error.Write( "H" );
  351. 			Console.ResetColor( );
  352. 			Console.Error.WriteLine( "ours in timespan" );
  353.  
  354. 			Console.ForegroundColor = ConsoleColor.White;
  355. 			Console.Error.Write( "                    /I" );
  356. 			Console.ResetColor( );
  357. 			Console.Error.Write( "    return total number of m" );
  358. 			Console.ForegroundColor = ConsoleColor.White;
  359. 			Console.Error.Write( "I" );
  360. 			Console.ResetColor( );
  361. 			Console.Error.WriteLine( "lliseconds in timespan" );
  362.  
  363. 			Console.ForegroundColor = ConsoleColor.White;
  364. 			Console.Error.Write( "                    /M" );
  365. 			Console.ResetColor( );
  366. 			Console.Error.Write( "    return total number of entire " );
  367. 			Console.ForegroundColor = ConsoleColor.White;
  368. 			Console.Error.Write( "M" );
  369. 			Console.ResetColor( );
  370. 			Console.Error.WriteLine( "inutes in timespan" );
  371.  
  372. 			Console.ForegroundColor = ConsoleColor.White;
  373. 			Console.Error.Write( "                    /R" );
  374. 			Console.ResetColor( );
  375. 			Console.Error.Write( "    return " );
  376. 			Console.ForegroundColor = ConsoleColor.White;
  377. 			Console.Error.Write( "R" );
  378. 			Console.ResetColor( );
  379. 			Console.Error.WriteLine( "aw timespan string (+/-dd.hh:mm:ss.iii000000)" );
  380.  
  381. 			Console.ForegroundColor = ConsoleColor.White;
  382. 			Console.Error.Write( "                    /S" );
  383. 			Console.ResetColor( );
  384. 			Console.Error.Write( "    return total number of entire " );
  385. 			Console.ForegroundColor = ConsoleColor.White;
  386. 			Console.Error.Write( "S" );
  387. 			Console.ResetColor( );
  388. 			Console.Error.WriteLine( "econds in timespan" );
  389.  
  390. 			Console.ForegroundColor = ConsoleColor.White;
  391. 			Console.Error.Write( "                    /T" );
  392. 			Console.ResetColor( );
  393. 			Console.Error.Write( "    return total number of " );
  394. 			Console.ForegroundColor = ConsoleColor.White;
  395. 			Console.Error.Write( "T" );
  396. 			Console.ResetColor( );
  397. 			Console.Error.WriteLine( "icks in timespan" );
  398.  
  399. 			Console.ForegroundColor = ConsoleColor.White;
  400. 			Console.Error.Write( "                    /V    V" );
  401. 			Console.ResetColor( );
  402. 			Console.Error.WriteLine( "erbose output string, including leading and trailing" );
  403.  
  404. 			Console.Error.WriteLine( "                          zeroes (e.g. 0 years, or 0 milliseconds)" );
  405.  
  406. 			Console.ForegroundColor = ConsoleColor.White;
  407. 			Console.Error.Write( "                    /W" );
  408. 			Console.ResetColor( );
  409. 			Console.Error.Write( "    return total number of entire " );
  410. 			Console.ForegroundColor = ConsoleColor.White;
  411. 			Console.Error.Write( "W" );
  412. 			Console.ResetColor( );
  413. 			Console.Error.WriteLine( "eeks in timespan" );
  414.  
  415. 			Console.ForegroundColor = ConsoleColor.White;
  416. 			Console.Error.Write( "                    /Y" );
  417. 			Console.ResetColor( );
  418. 			Console.Error.Write( "    return number of entire " );
  419. 			Console.ForegroundColor = ConsoleColor.White;
  420. 			Console.Error.Write( "Y" );
  421. 			Console.ResetColor( );
  422. 			Console.Error.WriteLine( "ears in timespan" );
  423.  
  424. 			Console.Error.WriteLine( );
  425.  
  426. 			Console.Error.WriteLine( "Notes:    Dates must be entered either in YYYY-MM-DD [hh:mm[:ss[.iii]]] format," );
  427.  
  428. 			Console.Error.Write( "          or in local system's date/time format with " );
  429. 			Console.ForegroundColor = ConsoleColor.White;
  430. 			Console.Error.Write( "DOT" );
  431. 			Console.ResetColor( );
  432. 			Console.Error.WriteLine( " for decimal delimiter," );
  433.  
  434. 			Console.Error.Write( "          or as " );
  435. 			Console.ForegroundColor = ConsoleColor.White;
  436. 			Console.Error.Write( "\"Now\"" );
  437. 			Console.ResetColor( );
  438. 			Console.Error.WriteLine( ", in which case the current date and time will be used." );
  439.  
  440. 			Console.Error.WriteLine( "          In both dates, date and time components are optional, but at least" );
  441.  
  442. 			Console.Error.WriteLine( "          one of these must be specified: if no date is specified, today is" );
  443.  
  444. 			Console.Error.WriteLine( "          assumed, if no time is specified, 00:00:00.000000000 is assumed." );
  445.  
  446. 			Console.Error.WriteLine( "          Default output: years, days, hours, minutes, seconds, milliseconds;" );
  447.  
  448. 			Console.Error.Write( "          first value shown will be first non-zero value, unless " );
  449. 			Console.ForegroundColor = ConsoleColor.White;
  450. 			Console.Error.Write( "/V" );
  451. 			Console.ResetColor( );
  452. 			Console.Error.WriteLine( " specified;" );
  453.  
  454. 			Console.Error.Write( "          milliseconds will not be shown if zero, unless " );
  455. 			Console.ForegroundColor = ConsoleColor.White;
  456. 			Console.Error.Write( "/V" );
  457. 			Console.ResetColor( );
  458. 			Console.Error.Write( " or " );
  459. 			Console.ForegroundColor = ConsoleColor.White;
  460. 			Console.Error.Write( "/I" );
  461. 			Console.ResetColor( );
  462. 			Console.Error.WriteLine( " is specified." );
  463.  
  464. 			Console.Error.WriteLine( "          Return code (\"ErrorLevel\") equals absolute value of the result for" );
  465.  
  466. 			Console.ForegroundColor = ConsoleColor.White;
  467. 			Console.Error.Write( "          /D" );
  468. 			Console.ResetColor( );
  469. 			Console.Error.Write( " or " );
  470. 			Console.ForegroundColor = ConsoleColor.White;
  471. 			Console.Error.Write( "/H" );
  472. 			Console.ResetColor( );
  473. 			Console.Error.Write( " or " );
  474. 			Console.ForegroundColor = ConsoleColor.White;
  475. 			Console.Error.Write( "/M" );
  476. 			Console.ResetColor( );
  477. 			Console.Error.Write( " or " );
  478. 			Console.ForegroundColor = ConsoleColor.White;
  479. 			Console.Error.Write( "/S" );
  480. 			Console.ResetColor( );
  481. 			Console.Error.Write( " or " );
  482. 			Console.ForegroundColor = ConsoleColor.White;
  483. 			Console.Error.Write( "/W" );
  484. 			Console.ResetColor( );
  485. 			Console.Error.Write( " or " );
  486. 			Console.ForegroundColor = ConsoleColor.White;
  487. 			Console.Error.Write( "/Y" );
  488. 			Console.ResetColor( );
  489. 			Console.Error.WriteLine( " switches; otherwise 0 if result is" );
  490.  
  491. 			Console.Error.WriteLine( "          valid or 1 in case of (command line) errors." );
  492.  
  493. 			Console.Error.WriteLine( );
  494.  
  495. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  496.  
  497. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  498. 			return rc;
  499. 		}
  500.  
  501. 		#endregion Error handling
  502. 	}
  503. }
  504.  

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