Compare FileModifyDate and DateTimeOriginal within 3 seconds

Started by lei, April 12, 2025, 01:19:17 AM

Previous topic - Next topic

lei

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!

Phil Harvey

$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
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

lei

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!

greybeard

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

StarGeek

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 rather than the DateFmt helper function. Also, the hashtag version of the -n (--printConv) option 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.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

lei

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!

greybeard

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

The simplified option is always the better option

lei

Quote from: greybeard on April 12, 2025, 12:36:35 PM
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

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.

lei

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!

StarGeek

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.

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

"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

lei

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!

StarGeek

The only place I can think of off hand that you can process two separate tags directly is in the -if option.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

lei

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.

Phil Harvey

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
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

StarGeek

Yes, Phil, that's exactly what I meant. Thanks for clarifying.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype