filename format (timestamp) for iphone photos?

Advanced Renamer forum
#1 : 28/06-21 06:01
Jonathan Grant
Posts: 8
I am trying to change the creation date attribute on photos created by iphone based on the date and time in the filename. Dropbox changes the file created by date to the time of upload, which is really annoying.

I am struggling to come up with a pattern that works. Here is an example of a filename: "Photo Jun 26, 12 33 28 PM.heic"

I tried <Month:Xxx> <Day>, <hour> <min> <sec>
but that did not work. Tried it with normal <Month>, but that didn't work either. Am I missing something?
#2 : 28/06-21 10:05
David Lee
Posts: 1125
Firstly, the Windows "Date Created" is the date that the copy of the file was created in Windows NOT the creation date of the original file. If the file has not been modified since it was first created then "Date Modified" will probably be the original creation date.

The problem with your pattern is that all date/time fields must be numerical so <Month:Xxx> is not acceptable in this context. So you will have to modify the filename before applying the Timestamp method. Unfortunately this method operates on the original filename, so you will have to run two separate batches - the first to rename the files and the second to modify the timestamps and undo the renaming.

To simplify the renaming I would first duplicate the original filenames, with the two parts separated by a character that will never be used in a file - eg "#".

So

First batch...

1) New Name method
New Name: <Name>#<Name>

2) List replace method
One line for each month...
Text to be replaced: Jan(?=.*#)
Replace with: 01
etc
Check: "Use regular expressions".

Note: "(?=.*#)" is a "positive lookahead". This specifies that the month name will only match if it is followed by a string containing "#" - ie only the month name in the first part of the filename will be replaced by a number.

Run the batch, reloading all files

Second batch...

1) Timestamp method
Filename pattern: <Month> <Day>, <hour> <min> <sec>

2) Replace method
Text to be replaced: *#
Replace with: leave blank
"Use regular expressions" NOT checked.


It should be possible to carry this out in a single pass using a script - however, whilst you can set the New Created Date in the list (by writing to item.newCreatedDate) this new value is ignored by Advance Renamer when the batch is run.

edited: 28/06-21 11:12
#3 : 28/06-21 21:15
Jonathan Grant
Posts: 8
Reply to #2:

Thanks for your response! Is it a problem that the time used is not military time? The filename ends in either AM or PM.
#4 : 29/06-21 00:59
David Lee
Posts: 1125
Reply to #3:
Only you can answer that question!

The suggested solution will not distinguish between AM and PM - if that is a problem then you can easily convert the time to 24hour format using a script.

Replace the New name method in the first batch with a script method using the following code:

name = item.name;
match = name.match(/^(.*, )(\d{2})(.*) (AM|PM)/);
hr = 1*match[2];
if (match[4] == 'AM') {
if (hr == 12) hr = 0;
} else {
if (hr != 12) hr += 12;
}
return match[1] + ('0' + hr).slice(-2) + match[3] + '#' + name;


This assumes the "military time" convention that midnight is 12AM and noon is 12PM.
The filename is restored to the original AM/PM format.
#5 : 30/06-21 22:35
Jonathan Grant
Posts: 8
Reply to #4:
Hmm, this doesn't seem to be working. It says invalid script. I selected "script" and replaced the contents with what you posted (copy and paste).
#6 : 01/07-21 18:11
David Lee
Posts: 1125
Reply to #5:
Strange - I've just checked and it works for me.

Are you sure that you selected the script correctly?
Try again and post the error message if it fails again (you can copy it from the JS console).

name = item.name;
match = name.match(/^(.*, )(\d{2})(.*) (AM|PM)/);
hr = 1*match[2];
if (match[4] == 'AM') {
if (hr == 12) hr = 0;
} else {
if (hr != 12) hr += 12;
}
return match[1] + ('0' + hr).slice(-2) + match[3] + '#' + name;
#7 : 01/07-21 21:32
Jonathan Grant
Posts: 8
Reply to #6:
Now it is saying "access violation at address 00000000 in module ARen.exe.
Read of address 00000000

It didn't give this error last time.

Before it just gave the error "(124) invalid script" for each file, then in JS console it says "line 3: match is null"

edited: 01/07-21 21:35
#8 : 08/07-21 01:55
Jonathan Grant
Posts: 8
Reply to #7:
did I give you the information you needed?
#9 : 09/07-21 00:50
David Lee
Posts: 1125
Reply to #8:
There's nothing more I can suggest - other that there must be something wrong with your script or filename.

I have pasted the above code into a script method and copied and pasted your example filename (Photo Jun 26, 12 33 28 PM.heic) into the list and the script works perfectly for me.

I'm using ARen 3.87 running on Windows 10 pro.

However "line 3: match is null" indicates that the regular expression in line 2 is not finding a match.

match = name.match(/^(.*, )(\d{2})(.*) (AM|PM)/);

match should return an array containing the overall match in element 0 and the individual sub-expression matches in subsequent array elements.

So for the above filename...
The total match should be : "Photo Jun 26, 12 33 28 PM" = match[0]
(.*, ) = "Photo Jun 26, " = match[1]
(\d{2}) = "12" = match[2]
(.*) = " 33 28" = match[3]
(AM|PM) = "PM" = match[4]

You can check what is actually being returned by inserting a log() command in the script

ie

name = item.name;
match = name.match(/^(.*, )(\d{2})(.*) (AM|PM)/);
log(match);
hr = 1*match[2];
if (match[4] == 'AM') {
if (hr == 12) hr = 0;
} else {
if (hr != 12) hr += 12;
}
return match[1] + ('0' + hr).slice(-2) + match[3] + '#' + name;

This will print the contents of the variable "match" to the JS Console.

Your example filename should return...

[
"Photo Jun 26, 12 33 28 PM",
"Photo Jun 26, ",
"12",
" 33 28",
"PM"
]



edited: 09/07-21 09:21
#10 : 09/07-21 17:29
Jonathan Grant
Posts: 8
Reply to #9:
Okay, I got this error in the jsconsole: line 4: match is null

I will copy and paste the script below:

name = item.name;
match = name.match(/^(.*, )(\d{2})(.*) (AM|PM)/);
log(match);
hr = 1*match[2];
if (match[4] == 'AM') {
if (hr == 12) hr = 0;
} else {
if (hr != 12) hr += 12;
}
return match[1] + ('0' + hr).slice(-2) + match[3] + '#' + name;

I am using Windows 10 as well, and recently updated renamer.

Here is a copy and paste of one of the filenames, in case I made a typo before: Photo Jul 08, 1 02 35 PM.heic

edited: 09/07-21 17:30
#11 : 10/07-21 00:06
Jonathan Grant
Posts: 8
Reply to #10:
Okay, I deleted everything after the log (line #4 on) and ran it. It then ran successfully and gave the following output:

null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
null
[
"Photo Jul 08, 12 55 45 PM",
"Photo Jul 08, ",
"12",
" 55 45",
"PM"
]
[
"Photo Jul 08, 12 55 54 PM",
"Photo Jul 08, ",
"12",
" 55 54",
"PM"
]
[
"Photo Jul 08, 12 55 55 PM",
"Photo Jul 08, ",
"12",
" 55 55",
"PM"
]
[
"Photo Jul 08, 12 58 11 PM",
"Photo Jul 08, ",
"12",
" 58 11",
"PM"
]
[
"Photo Jul 08, 12 58 19 PM",
"Photo Jul 08, ",
"12",
" 58 19",
"PM"
]
[
"Photo Jul 08, 12 58 26 PM",
"Photo Jul 08, ",
"12",
" 58 26",
"PM"
]
[
"Photo Jul 08, 12 58 38 PM",
"Photo Jul 08, ",
"12",
" 58 38",
"PM"
]
null
null
null
null
null
null
null
null
null
null
null

The null results are files in which the hour in the filename was NOT 12. This should help point to the issue!
#12 : 10/07-21 14:52
David Lee
Posts: 1125
Reply to #11:

Slight red-herring - the script still works fine when the hour is 10 or 11. The problem is that the regex "(\d{2})" is expecting a 2-digit hour - ie with a leading zero, where necessary.

The fix is easy - simply replace this with "(\d{1,2})".

"{n,m}" means: Match the previous character or metacharacter at least n times but no more than m times. So "(\d{1,2})" will match and save either one or two decimal digits.

There is a basic introduction to the use of regular expressions in renaming methods in the User Guide at www.advancedrenamer.com/user_guide/regular_expresions. Regex behave in mostly the same way in a script - except that JavaScript uses pairs of "/" characters to define a regular expression in the same way that you would use paired single or double quotes to define a string.

Also see www.advancedrenamer.com/user_guide/method_script
and www.advancedrenamer.com/user_guide/example_scripting for a basic introduction to scripting.

For more detailed information you will need to use a Google search - I find results at www.w3schools.com particularly helpful.

My go-to site for advanced regular expressions is www.regular-expressions.info

edited: 10/07-21 14:53
#13 : 11/07-21 04:51
Jonathan Grant
Posts: 8
Reply to #12:
AHA! I think this did the trick!
#14 : 11/07-21 17:48
David Lee
Posts: 1125
Reply to #13:
Got there in the end - glad it worked!
#15 : 26/08-21 18:36
Yoram
Posts: 1
Reply to #2:
If <Month:Xxx> cannot be used in a pattern in Timestamp trying to match a date in a file name, then I don't understand where it CAN be used...

In any case, if really it cannot be used in this context, I find it to be a significant shortcoming of the program. A tag is (or rather, should be...) a tag is a tag...
#16 : 27/08-21 18:46
David Lee
Posts: 1125
Reply to #15:
Try reading the User Guide!

Quote:

Filename pattern / Dirname pattern
When checked a pattern edit field will be visible in the bottom. In this field a pattern for how the date and time values can be retrieved from the file or parent directory name. The tags <Year>, <Month>, <Day>, <Hour>, <Min>, and <Sec> have special meaning in this method. They are used to specify how the date and time parts are recognized in the name.

Example: If you have a filename with year, month, and day values in the name and you want to set the file date to this date and the filename is "Summer at the lake 2011-04-01.jpg" the pattern <Year>-<Month>-<Day> will automatically retrieve the date.

Regular tags can also be used in the pattern, but note that the six date and time tags have special meaning here.

edited: 27/08-21 18:47