Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for capturedate.cs

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text.RegularExpressions;
  5.  
  6.  
  7. namespace RobvanderWoude
  8. {
  9. 	class CaptureDate
  10. 	{
  11. 		static string progver = "1.01";
  12.  
  13.  
  14. 		static int Main( string[] args )
  15. 		{
  16. 			string filename = String.Empty;
  17. 			bool confirmsettimestamp = true;
  18. 			bool readabletimestamp = true;
  19. 			bool settimestamp = false;
  20.  
  21.  
  22. 			#region Parse Command Line
  23.  
  24. 			if ( args.Length == 0 )
  25. 			{
  26. 				return ShowHelp( );
  27. 			}
  28.  
  29. 			if ( args.Length > 4 )
  30. 			{
  31. 				return ShowHelp( "Too many command line arguments" );
  32. 			}
  33.  
  34. 			foreach ( string arg in args )
  35. 			{
  36. 				if ( arg == "/?" )
  37. 				{
  38. 					return ShowHelp( );
  39. 				}
  40. 				if ( arg[0] == '/' )
  41. 				{
  42. 					switch ( arg.ToUpper( ) )
  43. 					{
  44. 						case "/S":
  45. 							if ( settimestamp )
  46. 							{
  47. 								return ShowHelp( "Duplicate switch: \"/S\"" );
  48. 							}
  49. 							settimestamp = true;
  50. 							break;
  51. 						case "/T":
  52. 							if ( !readabletimestamp )
  53. 							{
  54. 								return ShowHelp( "Duplicate switch: \"/T\"" );
  55. 							}
  56. 							readabletimestamp = false;
  57. 							break;
  58. 						case "/Y":
  59. 							if ( !confirmsettimestamp )
  60. 							{
  61. 								return ShowHelp( "Duplicate switch: \"/Y\"" );
  62. 							}
  63. 							confirmsettimestamp = false;
  64. 							break;
  65. 						default:
  66. 							return ShowHelp( "Invalid switch: \"{0}\"", arg );
  67. 					}
  68. 				}
  69. 				else
  70. 				{
  71. 					if ( !String.IsNullOrEmpty( filename ) )
  72. 					{
  73. 						return ShowHelp( "Invalid or duplicate argument(s)" );
  74. 					}
  75. 					filename = arg;
  76. 					if ( !String.IsNullOrEmpty( Path.GetDirectoryName( filename ) ) && !Directory.Exists( Path.GetDirectoryName( filename ) ) )
  77. 					{
  78. 						return ShowHelp( "Folder not found: \"{0}\"", Path.GetDirectoryName( filename ) );
  79. 					}
  80. 					if ( !File.Exists( filename ) )
  81. 					{
  82. 						return ShowHelp( "File not found: \"{0}\"", filename );
  83. 					}
  84. 				}
  85. 			}
  86. 			if ( string.IsNullOrEmpty( filename ) )
  87. 			{
  88. 				return ShowHelp( "No file specified" );
  89. 			}
  90. 			if ( !confirmsettimestamp && !settimestamp )
  91. 			{
  92. 				return ShowHelp( "/Y switch is valid only when combined with /S switch." );
  93. 			}
  94.  
  95. 			#endregion Parse Command Line
  96.  
  97.  
  98. 			try
  99. 			{
  100. 				StreamReader file = new StreamReader( filename );
  101. 				char[] buffer = new char[1024];
  102. 				int result = file.Read( buffer, 0, 1023 );
  103. 				file.Close( );
  104. 				string header = new string( buffer );
  105.  
  106. 				if ( string.IsNullOrEmpty( header ) )
  107. 				{
  108. 					return ShowHelp( "Could not open file \"{0}\"", filename );
  109. 				}
  110.  
  111. 				string pattern = "\\b[12]\\d{3}:[01]\\d:[0-3]\\d [0-2]\\d:[0-5]\\d:[0-5]\\d\\b";
  112. 				Regex regexp = new Regex( pattern, RegexOptions.None );
  113. 				MatchCollection matches = regexp.Matches( header );
  114. 				if ( matches.Count == 0 )
  115. 				{
  116. 					return ShowHelp( "No capture date found in file header" );
  117. 				}
  118. 				string photodatedelimited = String.Empty;
  119. 				foreach ( Match match in matches )
  120. 				{
  121. 					if ( string.IsNullOrEmpty( photodatedelimited ) || String.Compare( photodatedelimited, match.Value, StringComparison.Ordinal ) > 0 )
  122. 					{
  123. 						photodatedelimited = match.Value;
  124. 					}
  125. 				}
  126. 				photodatedelimited = photodatedelimited.Substring( 0, 10 ).Replace( ":", "-" ) + photodatedelimited.Substring( 10 );
  127. 				string photodatenodelims = photodatedelimited.Replace( ":", "" ).Replace( "-", "" ).Replace( " ", "T" );
  128. 				if ( settimestamp )
  129. 				{
  130. 					string timeformat;
  131. 					if ( readabletimestamp )
  132. 					{
  133. 						timeformat = "{0:yyyy}-{0:MM}-{0:dd} {0:HH}:{0:mm}:{0:ss}";
  134. 					}
  135. 					else
  136. 					{
  137. 						timeformat = "{0:yyyy}{0:MM}{0:dd}T{0:HH}{0:mm}{0:ss}";
  138. 					}
  139. 					DateTime currenttimestamp = File.GetLastWriteTime( filename );
  140. 					DateTime newtimestamp = DateTime.Parse( "01-01-0001 00:00:00" );
  141. 					if ( DateTime.TryParse( photodatedelimited, out newtimestamp ) )
  142. 					{
  143. 						if ( DateTime.Compare( currenttimestamp, newtimestamp ) == 0 )
  144. 						{
  145. 							if ( readabletimestamp )
  146. 							{
  147. 								Console.WriteLine( photodatedelimited );
  148. 							}
  149. 							else
  150. 							{
  151. 								Console.WriteLine( photodatenodelims );
  152. 							}
  153. 						}
  154. 						else
  155. 						{
  156. 							double timediff = Math.Abs( ( currenttimestamp - newtimestamp ).Hours );
  157. 							// Ignore time differences of one hour or less
  158. 							if ( timediff > 1 )
  159. 							{
  160. 								Console.WriteLine( "Image file name   : {0}", filename );
  161. 								Console.WriteLine( "Current timestamp : " + timeformat, currenttimestamp );
  162. 								Console.WriteLine( "Capture timestamp : " + timeformat, newtimestamp );
  163. 								if ( confirmsettimestamp )
  164. 								{
  165. 									Console.Write( "Do you want to change the file's timestamp to the capture time? [yN] " );
  166. 									string answer = Console.ReadKey( ).KeyChar.ToString( ).ToUpper( );
  167. 									if ( answer == "Y" )
  168. 									{
  169. 										File.SetLastWriteTime( filename, newtimestamp );
  170. 										Console.WriteLine( "\nNew timestamp     : " + timeformat, File.GetLastWriteTime( filename ) );
  171. 									}
  172. 									else
  173. 									{
  174. 										Console.WriteLine( "\naborting . . ." );
  175. 									}
  176. 								}
  177. 								else
  178. 								{
  179. 									File.SetLastWriteTime( filename, newtimestamp );
  180. 									Console.WriteLine( "New timestamp     : " + timeformat, File.GetLastWriteTime( filename ) );
  181. 								}
  182.  
  183. 							}
  184. 							else
  185. 							{
  186. 								Console.WriteLine( photodatedelimited );
  187. 							}
  188. 						}
  189. 					}
  190. 					else
  191. 					{
  192. 						return ShowHelp( "Could not determine timestamp of \"{0}\"", filename );
  193. 					}
  194. 				}
  195. 				else
  196. 				{
  197. 					Console.WriteLine( photodatedelimited );
  198. 				}
  199.  
  200. 				return 0;
  201. 			}
  202. 			catch ( Exception e )
  203. 			{
  204. 				return ShowHelp( e.Message );
  205. 			}
  206. 		}
  207.  
  208.  
  209. 		static string Today( bool usedelims = true )
  210. 		{
  211. 			string dateformat;
  212. 			if ( usedelims )
  213. 			{
  214. 				dateformat = "{0:yyyy}-{0:MM}-{0:dd} {0:HH}:{0:mm}:{0:ss}";
  215. 			}
  216. 			else
  217. 			{
  218. 				dateformat = "{0:yyyy}{0:MM}{0:dd}T{0:HH}{0:mm}{0:ss}";
  219. 			}
  220. 			return String.Format( dateformat, DateTime.Now );
  221. 		}
  222.  
  223.  
  224. 		#region Error handling
  225.  
  226. 		public static int ShowHelp( params string[] errmsg )
  227. 		{
  228. 			#region Error Message
  229.  
  230. 			if ( errmsg.Length > 0 )
  231. 			{
  232. 				List<string> errargs = new List<string>( errmsg );
  233. 				errargs.RemoveAt( 0 );
  234. 				Console.Error.WriteLine( );
  235. 				Console.ForegroundColor = ConsoleColor.Red;
  236. 				Console.Error.Write( "ERROR:\t" );
  237. 				Console.ForegroundColor = ConsoleColor.White;
  238. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  239. 				Console.ResetColor( );
  240. 			}
  241.  
  242. 			#endregion Error Message
  243.  
  244.  
  245. 			#region Help Text
  246.  
  247. 			/*
  248. 			CaptureDate,  Version 1.01
  249. 			Return the capture date and time for the specified image file
  250.  
  251. 			Usage:   CAPTUREDATE  image  [ /T ]  [ /S  [ /Y ] ]
  252.  
  253. 			Where:   image    specifies the image file
  254. 			         /S       set the image file's timestamp to the capture date and time
  255. 			         /T       return the timestamp without "-" and ":" delimiters,
  256. 			                  e.g. 20171114T135628 instead of 2017-11-14 13:56:28
  257. 			         /Y       do not ask for confirmation before changing the image
  258. 			                  file's timestamp (requires /S switch)
  259.  
  260. 			Notes:   Result will be displayed on screen, e.g. 2017-11-14 13:56:28.
  261. 			         The date/time is extracted by searching for the earliest date/time
  262. 			         in the first 1024 bytes of the image file.
  263. 			         With /S switch used, the timestamp is changed only if the difference
  264. 			         between the current timestamp and the capture time exceeds 1 hour.
  265. 			         The program will ask for confirmation before changing the file's
  266. 			         timestamp, unless the /Y switch is used.
  267. 			         Return code ("errorlevel") is -1 in case of errors or if no valid
  268. 			         date was found, or 0 otherwise.
  269.  
  270. 			Written by Rob van der Woude
  271. 			http://www.robvanderwoude.com
  272. 			*/
  273.  
  274. 			string timestampDelimited = Today( true );
  275. 			string timestampNodelims = Today( false );
  276. 			Console.Error.WriteLine( );
  277. 			Console.Error.WriteLine( "CaptureDate,  Version {0}", progver );
  278. 			Console.Error.WriteLine( "Return the capture date and time for the specified image file" );
  279. 			Console.Error.WriteLine( );
  280. 			Console.Error.Write( "Usage:   " );
  281. 			Console.ForegroundColor = ConsoleColor.White;
  282. 			Console.Error.WriteLine( "CAPTUREDATE  image  [ /T ]  [ /S  [ /Y ] ]" );
  283. 			Console.ResetColor( );
  284. 			Console.Error.WriteLine( );
  285. 			Console.Error.Write( "Where:   " );
  286. 			Console.ForegroundColor = ConsoleColor.White;
  287. 			Console.Error.Write( "image" );
  288. 			Console.ResetColor( );
  289. 			Console.Error.WriteLine( "    specifies the image file" );
  290. 			Console.ForegroundColor = ConsoleColor.White;
  291. 			Console.Error.Write( "         /S" );
  292. 			Console.ResetColor( );
  293. 			Console.Error.WriteLine( "       set the image file's timestamp to the capture date and time" );
  294. 			Console.ForegroundColor = ConsoleColor.White;
  295. 			Console.Error.Write( "         /T" );
  296. 			Console.ResetColor( );
  297. 			Console.Error.WriteLine( "       return the timestamp without \"-\" and \":\" delimiters," );
  298. 			Console.Error.Write( "                  e.g. " );
  299. 			Console.ForegroundColor = ConsoleColor.White;
  300. 			Console.Error.Write( timestampNodelims );
  301. 			Console.ResetColor( );
  302. 			Console.Error.Write( " instead of " );
  303. 			Console.ForegroundColor = ConsoleColor.White;
  304. 			Console.Error.Write( timestampDelimited );
  305. 			Console.ResetColor( );
  306. 			Console.Error.WriteLine( "." );
  307. 			Console.ForegroundColor = ConsoleColor.White;
  308. 			Console.Error.Write( "         /Y" );
  309. 			Console.ResetColor( );
  310. 			Console.Error.WriteLine( "       do not ask for confirmation before changing the image" );
  311. 			Console.Error.Write( "                  file's timestamp (requires " );
  312. 			Console.ForegroundColor = ConsoleColor.White;
  313. 			Console.Error.Write( "/S" );
  314. 			Console.ResetColor( );
  315. 			Console.Error.WriteLine( " switch)" );
  316. 			Console.Error.WriteLine( );
  317. 			Console.Error.Write( "Notes:   Result will be displayed on screen, e.g. " );
  318. 			Console.ForegroundColor = ConsoleColor.White;
  319. 			Console.Error.Write( timestampDelimited );
  320. 			Console.ResetColor( );
  321. 			Console.Error.WriteLine( "." );
  322. 			Console.Error.WriteLine( "         The date/time is extracted by searching for the earliest date/time" );
  323. 			Console.Error.WriteLine( "         in the first 1024 bytes of the image file." );
  324. 			Console.Error.Write( "         With " );
  325. 			Console.ForegroundColor = ConsoleColor.White;
  326. 			Console.Error.Write( "/S" );
  327. 			Console.ResetColor( );
  328. 			Console.Error.WriteLine( " switch used, the timestamp is changed only if the difference" );
  329. 			Console.Error.WriteLine( "         between the current timestamp and the capture time exceeds 1 hour." );
  330. 			Console.Error.WriteLine( "         The program will ask for confirmation before changing the file's" );
  331. 			Console.Error.Write( "         timestamp, unless the " );
  332. 			Console.ForegroundColor = ConsoleColor.White;
  333. 			Console.Error.Write( "/Y" );
  334. 			Console.ResetColor( );
  335. 			Console.Error.WriteLine( " switch is used." );
  336. 			Console.Error.WriteLine( "         Return code (\"errorlevel\") is -1 in case of errors or if no valid" );
  337. 			Console.Error.WriteLine( "         date was found, or 0 otherwise." );
  338. 			Console.Error.WriteLine( );
  339. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  340. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  341.  
  342. 			#endregion Help Text
  343.  
  344.  
  345. 			return -1;
  346. 		}
  347.  
  348. 		#endregion Error handling
  349.  
  350. 	}
  351. }
  352.  

page last uploaded: 2017-08-21, 14:26