Hi there!
I'm trying to use ExifTool to list .jpg files in a folder where the FileModifyDate and DateTimeOriginal differ by no more than 3 seconds.
I tried using -if to compare the two tags, like this:
exiftool -if "abs($FileModifyDate - $DateTimeOriginal) <= 3" -filename -FileModifyDate -DateTimeOriginal -ext jpg .
But it doesn't return any results, even though I have files where the time difference is clearly less than 3 seconds. I suspect the problem is that these tags are strings and can't be compared directly like numbers.
Is there a correct way to compare these two timestamps with a tolerance (e.g. 3 seconds)? Or should I use another method?
I'm on Windows 10, using ExifTool version 12.92.
Thanks in advance!
$datetimeoriginal is a string as you suspected.
Unless you use the -d %s option, then it is converted to seconds since 1970, which you can use in your expression.
- Phil
Thanks, Phil. Based on your reply, I understand that -d %s only affects the output, not the internal comparison.
Could you please show me the exact ExifTool command that lists JPG files where FileModifyDate and DateTimeOriginal differ by no more than 3 seconds? I want to do this entirely inside ExifTool, without using shell, awk, or PowerShell.
Thanks in advance!
How about:
exiftool -if 'abs(${FileModifyDate;DateFmt("%s")}-${DateTimeOriginal;DateFmt("%s")}) < 4 ' -FileName -FileModifyDate -DateTimeOriginal -ext jpg -T .
This is MacOS you might need to switch single and double quotes on Windows
Quote from: lei on April 12, 2025, 08:58:12 AMThanks, Phil. Based on your reply, I understand that -d %s only affects the output, not the internal comparison.
No. This changes the value of the tag completely in the command it is used.
Example. This is a simplified version of @greybeard's command using only the
-d (
-dateFormat) option (https://exiftool.org/exiftool_pod.html#d-FMT--dateFormat) rather than the
DateFmt helper function (https://exiftool.org//exiftool_pod.html#Helper-functions). Also, the hashtag version of the
-n (
--printConv) option (https://exiftool.org/exiftool_pod.html#n---printConv) is used to display the unmodified values.
C:\>exiftool -G -a -s -DateTimeOriginal -FileModifyDate y:\!temp\Test4.jpg
[EXIF] DateTimeOriginal : 2025:04:12 12:00:00
[File] FileModifyDate : 2025:04:12 12:00:02-07:00
C:\>exiftool -G -a -s -d %s -if "abs($FileModifyDate-$DateTimeOriginal) < 4 " -FileName -FileModifyDate -DateTimeOriginal -FileModifyDate# -DateTimeOriginal# y:\!temp\Test4.jpg
[File] FileName : Test4.jpg
[File] FileModifyDate : 1744484402
[EXIF] DateTimeOriginal : 1744484400
[File] FileModifyDate : 2025:04:12 12:00:02-07:00
[EXIF] DateTimeOriginal : 2025:04:12 12:00:00
Also, make sure you're using CMD and not PowerShell. PowerShell's quoting rules are different from every other command line.
Thanks a ton, you guys are awesome! Phil's method is definitely spot-on; I just messed up by skipping a few options I shouldn't have, which led to some syntax errors. Greybeard's approach is no doubt correct as well. StarGeek's explanation really helped me understand a few proper uses better. Big thanks to all of you!
Quote from: StarGeek on April 12, 2025, 10:45:36 AM[This is a simplified version of @greybeard's command using only the -d (-dateFormat) option (https://exiftool.org/exiftool_pod.html#d-FMT--dateFormat)
The simplified option is always the better option
Quote from: greybeard on April 12, 2025, 12:36:35 PMQuote from: StarGeek on April 12, 2025, 10:45:36 AM[This is a simplified version of @greybeard's command using only the -d (-dateFormat) option (https://exiftool.org/exiftool_pod.html#d-FMT--dateFormat)
The simplified option is always the better option
Absolutely, when there are a bunch of tags in the command, simpler is better. But with just one or two, both methods work great. Thank you once again.
Dear Experts,
Now, I want to add something more.
Could anyone please tell me how to calculate the time difference between two timestamps in JPG files?
I want to find the time difference between -DateTimeOriginal and -FileModifyDate in a format like this:
Filename DateTimeOriginal FileModifyDate Difference
20250423_164706.jpg 2025:04:23 16:47:06 2025:04:23 16:47:44 38 sec
20250423_164809.jpg 2025:04:23 16:48:09 2025:04:23 16:48:10 1 sec
The first column is the filename, the second is -DateTimeOriginal, the third is -FileModifyDate, and the fourth is the time difference that I want to calculate.
Thanks in advance!
The cleanest solution is to create a user-defined tag to do this. To do this directly on the command line would be messy, and you would have to use the -p (-printFormat) option (https://exiftool.org/exiftool_pod.html#p-FMTFILE-or-STR--printFormat).
I'm also assuming you want the absolute difference between the two values.
Here's a config file that will calculate the difference and output it as a tag called MyTimeDiff.
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
#------------------------------------------------------------------------------
MyTimeDiff => {
Require => {
0 => 'DateTimeOriginal',
1 => 'FileModifyDate',
},
ValueConv => q{
return (abs(GetUnixTime($val[0])-GetUnixTime($val[1])));
},
},
#------------------------------------------------------------------------------
},
);
1; #end
If you have an .ExifTool_config file, you can cut the section between the bars and place that in the config file under the 'Image::ExifTool::Composite' => { line.
Example
C:\>exiftool -config MyTimeDiff.config -G1 -a -s -DateTimeOriginal -FileModifyDate -MyTimeDiff y:\!temp\Test4.jpg
inconfig
[ExifIFD] DateTimeOriginal : 2025:04:23 08:12:41
[System] FileModifyDate : 2025:04:23 08:00:00-07:00
[Composite] MyTimeDiff : 761
This would simplify your original comand with
-if "$MyTimeDiff< 4"
Using the -p option, your command would be
exiftool -p "$Filename $DateTimeOriginal $FileModifyDate ${DateTimeOriginal;$_=abs(GetUnixTime($_)-GetUnixTime($self->GetValue('FileModifyDate')))} /path/to/files/
Example
C:\>exiftool -p "$Filename $DateTimeOriginal $FileModifyDate ${DateTimeOriginal;$_=abs(GetUnixTime($_)-GetUnixTime($self->GetValue('FileModifyDate')))}" y:\!temp\Test4.jpg
Test4.jpg 2025:04:23 08:12:41 2025:04:23 08:00:00-07:00 761
Thanks a lot for your reply! Your solution works perfectly and helped me understand how ExifTool's expression syntax works, especially the use of $_ and $self->GetValue(...). I was wondering why I couldn't just use $FileModifyDate directly, and your solution made that clear. That really saved me a lot of time — thanks again!
The only place I can think of off hand that you can process two separate tags directly is in the -if option (https://exiftool.org/exiftool_pod.html#if-NUM-EXPR).
StarGeek!
Thanks again for your earlier post — I've been going over it and thinking things through before replying. Just one follow-up if you don't mind: when you mentioned that the only place where two separate tags can be processed directly is in the -if option, could you clarify a bit what makes -if different in this case? Were you referring mainly to logical comparisons like $tag1 ne $tag2, or is there more that -if allows compared to, say, -p expressions? I'm still learning my way around ExifTool, so any extra insight would be much appreciated.
I don't know what StarGeek meant by this, but the only real difference between -if and -p and expressions in -tagsfromfile arguments is that the -if condition is evaluated as a Perl expression and the others aren't.
- Phil
Yes, Phil, that's exactly what I meant. Thanks for clarifying.
Hi again,
Thanks so much for the earlier help with calculating the time difference between DateTimeOriginal and FileModifyDate. The command using:
-p "$Filename $DateTimeOriginal $FileModifyDate ${DateTimeOriginal;$_=abs(GetUnixTime($_)-GetUnixTime($self->GetValue('FileModifyDate')))}"
worked great, and it really helped me understand how flexible ExifTool can be. Also, thanks for clarifying the difference between -if and -p expressions — that cleared things up nicely.
While digging into how this works, I had a quick follow-up.
In the ${TAG;EXPR} format, I understand that $_ gives the value of the tag, and we can get other tags using $self->GetValue(...). But I was curious — is there any way to refer to another tag directly inside EXPR, like $FileModifyDate?
I tried it, but it didn't seem to work. The docs mention $_, $tag, and $self, but I couldn't find anything about tag variables being available directly. Just wanted to double-check if that's expected.
Thanks again — still getting my head around all the possibilities with ExifTool, and learning a lot.
It is not possible to refer to a tag directly (ie. "${TAG}") from within an advanced formatting expression for 3 reasons.
1. It introduces the possibility of a recursion that makes my brain explode. eg)
-p "${TAG1;$_=${TAG2;$_={TAG3;$_=${TAG4;$_='enough already!'}}}}"
2. It isn't very common that people want to do this anyway.
3. If you really need to, you already have access other tags via the API functions and the ExifTool $self object in the expression.
- Phil
Hi Phil,
Thank you so much for taking the time to explain all this in such detail. Your reply really helped me understand not only how it works, but also why it works that way. I learned a lot from this discussion.
Thanks again for your help and for developing such an amazing tool!
Best regards