Why does find -mtime +1 only return files older than 2 days?

I’m struggling to wrap my mind around why the find interprets file modification times the way it does. Specifically, I don’t understand why the -mtime +1 doesn’t show files less than 48 hours old.

As an example test I created three test files with different modified dates:

[root@foobox findtest]# ls -l
total 0
-rw-r--r-- 1 root root 0 Sep 25 08:44 foo1
-rw-r--r-- 1 root root 0 Sep 24 08:14 foo2
-rw-r--r-- 1 root root 0 Sep 23 08:14 foo3

I then ran find with the -mtime +1 switch and got the following output:

[root@foobox findtest]# find -mtime +1
./foo3

I then ran find with the -mmin +1440 and got the following output:

[root@foobox findtest]# find -mmin +1440
./foo3
./foo2

As per the man page for find, I understand that this is expected behavior:

 -mtime n
        File’s  data was last modified n*24 hours ago.  See the comments
        for -atime to understand how rounding affects the interpretation
        of file modification times.


-atime n
       File  was  last  accessed n*24 hours ago.  When find figures out
       how many 24-hour periods ago the file  was  last  accessed,  any
       fractional part is ignored, so to match -atime +1, a file has to
       have been accessed at least two days ago.

This still doesn’t make sense to me though. So if a file is 1 day, 23 hours, 59 minutes, and 59 seconds old, find -mtime +1 ignores all that and just treats it like it’s 1 day, 0 hours, 0 minutes, and 0 seconds old? In which case, it’s not technically older that 1 day and ignored?

Does… not… compute.

Asked By: Mike B

||

So if a file is 1 day, 23 hours, 59 minutes, and 59 seconds old, find -mtime +1 ignores all that and just treats it like it’s 1 day, 0 hours, 0 minutes, and 0 seconds old?

Yes. Like man find says, “any fractional part is ignored”. If you divide “1 day, 23 hours, 59 minutes, and 59 seconds” through “24 hours”, you may get 1.9999, but the .9999 part is then stripped and suddenly the file is only 1 day old.

Answered By: Martin von Wittich

Well, the simple answer is, I guess, that your find implementation is following the POSIX/SuS standard, which says it must behave this way. Quoting from SUSv4/IEEE Std 1003.1, 2013 Edition, “find”:

-mtime n
     The primary shall evaluate as true if the file modification time subtracted
     from the initialization time, divided by 86400 (with any remainder discarded), is n.

(Elsewhere in that document it explains that n can actually be +n, and the meaning of that as “greater than”).

As to why the standard says it shall behave that way—well, I’d guess long in the past a programmer was lazy or not thinking about it, and just wrote the C code (current_time - file_time) / 86400. C integer arithmetic discards the remainder. Scripts started depending on that behavior, and thus it was standardized.

The spec’d behavior would also be portable to a hypothetical system that only stored a modification date (not time). I don’t know if such a system has existed.

Answered By: derobert

Use -mmin, -amin, etc to get exact results

Answered By: Eran Ben-Natan

The argument to -mtime is interpreted as the number of whole days in the age of the file. -mtime +n means strictly greater than, -mtime -n means strictly less than.

Note that with Bash, you can do the more intuitive:

$ find . -mmin +$((60*24))
$ find . -mmin -$((60*24))

to find files older and newer than 24 hours, respectively.

(It’s also easier than typing in a fractional argument to -mtime for when you want resolution in hours or minutes.)

Answered By: Evgeni Sergeev

Fractional 24-hour periods are truncated! That means that “find -mtime +1” says to match files modified two or more days ago.

find . -mtime +0 # find files modified greater than 24 hours ago
find . -mtime 0 # find files modified between now and 1 day ago
# (i.e., in the past 24 hours only)
find . -mtime -1 # find files modified less than 1 day ago (SAME AS -mtime 0)
find . -mtime 1 # find files modified between 24 and 48 hours ago
find . -mtime +1 # find files modified more than 48 hours ago

The following may only work on GNU?

find . -mmin +5 -mmin -10 # find files modified between
# 6 and 9 minutes ago
find / -mmin -10 # modified less than 10 minutes ago
Answered By: Emir MurtaZa

-mtime N means files whose age A in days satisfies NA < N+1. In other words, -mtime N selects files that were last modified between N and N+1 days ago.

-mtime -N means files whose age A satisfies A < N, i.e. files modified less than N days ago. Less intuitively, -mtime +N means files whose age A satisfies N+1 ≤ A, i.e. files modified at least N+1 days ago.

For example, -mtime 1 selects files that were modified between 1 and 2 days ago. -mtime +1 selects files that were modified at least 2 days ago. To get files modified at least 1 day ago, use -mtime +0.

The description “was last modified n*24 hours ago” is only an approximation, and not a very clear one.

If you find these rules hard to remember, use a reference file instead.

touch -d '1 day ago' cutoff
find . -newer cutoff

(The syntax “1 day ago” requires GNU touch.)

If you want exactly 48-hours-old files, not 2 days, then you should add --daystart in your find command. This will help you.

find . type -f -daystart -mtime +1
Answered By: Aravind Goud
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.