{"id":64303,"date":"2007-08-04T01:17:00","date_gmt":"2007-08-04T01:17:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2007\/08\/04\/how-can-i-add-the-date-a-picture-was-taken-to-the-file-names-of-my-digital-photos\/"},"modified":"2007-08-04T01:17:00","modified_gmt":"2007-08-04T01:17:00","slug":"how-can-i-add-the-date-a-picture-was-taken-to-the-file-names-of-my-digital-photos","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-add-the-date-a-picture-was-taken-to-the-file-names-of-my-digital-photos\/","title":{"rendered":"How Can I Add the Date a Picture Was Taken to the File Names of My Digital Photos?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I rename all the .JPG files in a folder so that the date the picture was taken is included in the file name?<BR><BR>&#8212; NH <\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, NH. Welcome to <I>Hey, Scripting Guy!<\/I>, the only daily scripting column on TechNet that is written without the use of steroids, amphetamines, human growth hormone, or other forms of artificial enhancement. Each morning the Scripting Guy who writes this column undergoes extensive drug testing; so far, every one of these tests has come back negative. <I>Hey, Scripting Guy!<\/I>; written the way Nature intended it to be written.<\/P>\n<P>Interestingly enough, the Scripting Editor is continually dismayed by the fact that <I>Hey, Scripting Guy!<\/I> is written without the use of steroids, amphetamines, human growth hormone, or other forms of artificial enhancement. \u201cThis column is so boring,\u201d she says. \u201cYou really ought to try <I>something<\/I> to liven it up a bit. <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/aug07\/hey0802.mspx\"><B>Yesterday<\/B><\/A> you started out the column by saying, in effect, \u2018Well, I don\u2019t have anything interesting to say today.\u2019 No one wants to read stuff like that. If you won\u2019t take steroids at least do <I>something<\/I>!\u201d<\/P>\n<TABLE id=\"ETD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Ed<\/B><B>itor\u2019s Note:<\/B> We\u2019d like to note here that the Scripting Editor does not in any way endorse the taking of any performance-enhancing, performance-reducing, or performance-neutral drugs. The Scripting Editor does, however, endorse writing columns that are interesting but will still manage to keep the lawyers (or worse yet, our management) from coming after us for talking about things like\u2026well, just as an example\u2026steroids and amphetamines.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Well, with all due respect to the Scripting Editor, we beg to differ. <I>Liven it up a bit<\/I>?!? As our devoted readers know, practically every column we write features an amusing anecdote about the Scripting Son and his baseball team. How much more lively can you <I>get<\/I>?<\/P>\n<P>And even if he <I>does<\/I> occasionally have a day when he has nothing interesting to say, even if he occasionally has entire <I>years<\/I> when he has nothing interesting to say, well, the Scripting Guy who writes this column steadfastly refuses to take steroids, amphetamines, human growth hormone, or any other form of artificial enhancement. And why should he? After all, any time he needs a little excitement he can just crank out a script like this one:<\/P><PRE class=\"codeSample\">On Error Resume Next<\/p>\n<p>Set objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<\/p>\n<p>Set objConnection = CreateObject(&#8220;ADODB.Connection&#8221;)\nSet objRecordSet = CreateObject(&#8220;ADODB.Recordset&#8221;)<\/p>\n<p>objConnection.Open &#8220;Provider=Search.CollatorDSO;Extended Properties=&#8217;Application=Windows&#8217;;&#8221;<\/p>\n<p>objRecordSet.Open &#8220;SELECT System.ItemPathDisplay, System.Photo.DateTaken FROM SYSTEMINDEX Where System.ItemFolderPathDisplay = &#8216;C:\\Test'&#8221;, _\n    objConnection<\/p>\n<p>objRecordSet.MoveFirst<\/p>\n<p>Do Until objRecordset.EOF\n    strName = objRecordset.Fields.Item(&#8220;System.ItemPathDisplay&#8221;)\n    arrName = Split(strName, &#8220;.&#8221;)<\/p>\n<p>    dtmPhotoDate = objRecordset.Fields.Item(&#8220;System.Photo.DateTaken&#8221;)\n    strDay = Day(dtmPhotoDate)\n    strMonth = Month(dtmPhotoDate)\n    strYear = Year(dtmPhotoDate)\n    strNewName = arrName(0) &amp; &#8220;_&#8221; &amp; strMonth &amp; &#8220;_&#8221; &amp; strDay &amp; &#8220;_&#8221; &amp; strYear &amp; &#8220;.&#8221; &amp; arrName(1)<\/p>\n<p>    objFSO.MoveFile strName , strNewName\n    objRecordset.MoveNext\nLoop\n<\/PRE>\n<P>Wow, our head is still spinning and our heart is still pounding from <I>that<\/I> script!<\/P>\n<P>Give us a minute or two to come down off our high, and then we\u2019ll explain how this script works. Before we do that, however, we also need to issue one quick caveat. The date a digital photo was taken is retained any time that file is saved to a disk drive; to find the date, open Windows Explorer or My Computer, right-click the file, click <B>Properties<\/B>, click the <B>Summary<\/B> tab, and then click the <B>Advanced<\/B> button. (In Windows Vista, right-click, select Properties, then select the Details tab.) That\u2019s the good news. The bad news? There\u2019s nothing built into the operating system (prior to Windows Vista, that is) that allows a script writer to access this information. You can use the FileSystemObject or WMI to determine the date that the <I>file<\/I> was created (that is, the date the file was saved to the drive) but there\u2019s no way for you to determine the date that the picture was taken. None.<\/P>\n<P>So then how did we manage to write a script that can determine the date that a digital photo was taken and then add that date to the file name? That\u2019s easy: steroids.<\/P>\n<P>No, wait; sorry. As it turns out, we didn\u2019t use steroids; instead, we used <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/desktop\/wdsearch.mspx\"><B>Desktop Search 3.0<\/B><\/A>. (We always get those two things confused.) Granted, Desktop Search 3.0 is a piece of software you\u2019ll have to download, install, and configure before you can use it. (Unless you\u2019re running Windows Vista; in that case, the technology <I>is<\/I> included in the operating system.) That can be a hassle, and we\u2019re well aware that many people are reluctant to download and install new components such as this. On the other hand, Desktop Search 3.0 is pretty darn cool. And it\u2019s the only way we know of to solve this problem.<\/P>\n<P>We\u2019re not going to discuss the Desktop Search technology in any detail today; for more information about the technology and how it works, see our article <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/desktop\/wdsearch.mspx\"><B>Seek and Ye Shall Find<\/B><\/A>. Instead, we\u2019ll simply note that Desktop Search indexes selected folders and data stores on your computer (and yes, you have full control over what gets indexed and what doesn\u2019t), then exposes that information through ADO (ActiveX Data Objects). What does that mean? That means you can write a simple database script \u2013 and use a standard SQL query \u2013 to do all sorts of cool things. Like what? Well, like determine the date that a digital photo was taken.<\/P>\n<P>So then <I>how<\/I> do we determine the date that a digital photo was taken? To begin with, we create an instance of the <B>Scripting.FileSystemObject<\/B> object, something we\u2019ll use when it comes time to rename our files. We next create instances of the database objects <B>ADODB.Connection<\/B> and <B>ADODB.Recordset<\/B>, then use this line of code to the bind to the Desktop Search data store:<\/P><PRE class=\"codeSample\">objConnection.Open &#8220;Provider=Search.CollatorDSO;Extended Properties=&#8217;Application=Windows&#8217;;&#8221;\n<\/PRE>\n<P>Incidentally, all that initial setup and configuration is boilerplate; you can pretty much use the code exactly as-is in any script you write that uses Desktop Search. The part you\u2019ll need to change, and the part you\u2019ll need to focus on, is the SQL query:<\/P><PRE class=\"codeSample\">objRecordSet.Open &#8220;SELECT System.ItemPathDisplay, System.Photo.DateTaken FROM SYSTEMINDEX Where System.ItemFolderPathDisplay = &#8216;C:\\Test'&#8221;, _\n    objConnection\n<\/PRE>\n<P>Again, we won\u2019t discuss this in much detail today. Suffice to say that we are requesting information from the Desktop Search system index. What information are we requesting? We\u2019re asking for two property values: <B>System.ItemPathDisplay<\/B> (the file path) and <B>System.Photo.DateTaken<\/B> (the \u2013 well, you can figure out for yourself what this is). Of course, we don\u2019t want to retrieve this information for every file on the computer (although we could do so if we <I>did<\/I> want to). Instead, we only want this information for the files in the folder C:\\Test. That\u2019s what our Where clause is for: it limits returned data to items that have a <B>System.ItemFolderPathDisplay<\/B> (folder path) equal to C:\\Test.<\/P>\n<P>When we issue the <B>Open<\/B> command we get back a recordset consisting of the file path and photo date values for all the files in the folder C:\\Test. In order to add the photo date to each file name we need to loop through this set of files, something we do by setting up a Do Until loop that runs until the EOF (End of File )property is True:<\/P><PRE class=\"codeSample\">Do Until objRecordset.EOF\n<\/PRE>\n<P>So then what are we going to <I>do<\/I> in that recordset? Well, for starters, we\u2019re going to grab the file path for the first file in the collection and store that value in a variable named strName:<\/P><PRE class=\"codeSample\">strName = objRecordset.Fields.Item(&#8220;System.ItemPathDisplay&#8221;)\n<\/PRE>\n<P>That means that strName is going to be equal to something like C:\\Test\\100_0011.JPG. We\u2019ve decided to tack the photo date onto the end of the file name, giving our file a new name along the lines of C:\\Test\\100_0011_8_3_2007.JPG (assuming, of course, that the photo was taken on August 3, 2007). With that in mind, we use the <B>Split<\/B> function to take the file path and convert it to an array named arrName:<\/P><PRE class=\"codeSample\">arrName = Split(strName, &#8220;.&#8221;)\n<\/PRE>\n<P>By splitting on the dot (and, yes, we\u2019re assuming there\u2019s only one dot in the file name) we end up with an array consisting of the following elements:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>C:\\Test\\100_0011<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P>JPG<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Is that really going to help us rename the file? We\u2019ll find out in just a second.<\/P>\n<P>First, however, we need to grab the date that the picture was taken and store it in a variable named dtmPhotoDate:<\/P><PRE class=\"codeSample\">dtmPhotoDate = objRecordset.Fields.Item(&#8220;System.Photo.DateTaken&#8221;)\n<\/PRE>\n<P>After that, we use the following lines of code (and the VBScript functions <B>Day<\/B>, <B>Month<\/B>, and <B>Year<\/B>) to parse out the day (3), month (8), and year (2007) from the picture date: <\/P><PRE class=\"codeSample\">strDay = Day(dtmPhotoDate)\nstrMonth = Month(dtmPhotoDate)\nstrYear = Year(dtmPhotoDate)\n<\/PRE>\n<P>Got all that? Good; then you shouldn\u2019t have too much trouble understanding the following line of code:<\/P><PRE class=\"codeSample\">strNewName = arrName(0) &amp; &#8220;_&#8221; &amp; strMonth &amp; &#8220;_&#8221; &amp; strDay &amp; &#8220;_&#8221; &amp; strYear &amp; &#8220;.&#8221; &amp; arrName(1)\n<\/PRE>\n<P>All we\u2019re doing here is constructing a new file path, a path consisting of the following elements:<\/P>\n<TABLE border=\"0\" cellSpacing=\"0\" cellPadding=\"0\">\n<TBODY>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>C:\\Test\\100_0011<\/B> (item 0 in the array arrName)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>_<\/B><\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>8<\/B> (the value of the variable strMonth)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>_<\/B><\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>3<\/B> (the value of the variable strDay)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>_<\/B><\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>2007<\/B> (the value of the variable strYear)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>.<\/B><\/P><\/TD><\/TR>\n<TR>\n<TD class=\"listBullet\" vAlign=\"top\">\u2022<\/TD>\n<TD class=\"listItem\">\n<P><B>JPG<\/B> (item 1 in the array)<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>What does all that add up to? That all adds up to this: C:\\Test\\100_0011_8_3_2007.JPG. And yes, that <I>is<\/I> our original file path, plus the date that the photo was taken.<\/P>\n<P>The rest is easy. To rename the file, we use the FileSystemObject and the <B>MoveFile<\/B> method, like so:<\/P><PRE class=\"codeSample\">objFSO.MoveFile strName , strNewName\n<\/PRE>\n<P>Admittedly, this is a funny way to rename files; instead of using a command like Rename we \u201cmove\u201d the file from its old path (C:\\Test\\100_0011.JPG) to its new path (C:\\Test\\100_0011_8_3_2007.JPG). Not the most intuitive operation in the world, but, in the end, the file gets renamed, which is all we really care about.<\/P>\n<P>From there we simply call the <B>MoveNext<\/B> method to move on to the next file in the recordset. And that, as they say, is that.<\/P>\n<P>In the interests of full disclosure, we should note that the Scripting Guy who writes this column doesn\u2019t <I>really<\/I> undergo drug testing each and every morning. (If he did, any tests for steroids, amphetamines, or human growth hormone would come back negative. However, any tests for doughnuts or maple bars would likely come back positive.) We realize that this is hard to believe; after reading <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/jul06\/hey0714.mspx\"><B>some of our columns<\/B><\/A> your first reaction is likely to be, \u201cMan, what kind of drugs is <I>this<\/I> guy on?!?\u201d But no, <I>Hey, Scripting Guy!<\/I> is drug-free. You know what they say: winners don\u2019t use drugs.<\/P>\n<P>Well, OK, maybe <A href=\"http:\/\/sports.espn.go.com\/oly\/cycling\/news\/story?id=2896276&amp;campaign=rss&amp;source=ESPNHeadlines\" target=\"_blank\"><B>Tour de France winners<\/B><\/A> do. But other winners don\u2019t. And neither does the Scripting Guy who writes this column.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I rename all the .JPG files in a folder so that the date the picture was taken is included in the file name?&#8212; NH Hey, NH. Welcome to Hey, Scripting Guy!, the only daily scripting column on TechNet that is written without the use of steroids, amphetamines, human growth hormone, [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[38,122,123,3,12,5],"class_list":["post-64303","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-files","tag-graphics","tag-multimedia","tag-scripting-guy","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I rename all the .JPG files in a folder so that the date the picture was taken is included in the file name?&#8212; NH Hey, NH. Welcome to Hey, Scripting Guy!, the only daily scripting column on TechNet that is written without the use of steroids, amphetamines, human growth hormone, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64303","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=64303"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/64303\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=64303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=64303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=64303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}