Syncing DEVONthink & Finder’s Opened Dates?

By chance, does anyone have a script for syncing DEVONthink’s “Date Opened” field with Finder’s “Date Last Opened” that they’d be willing to share?

For those of us who index files with DEVONthink, you’ve probably noticed that this field doesn’t sync between DEVONthink and Finder. This can be a little frustrating when trying to use Finder (e.g., the Recents smart rule, sorting with the column is largely useless, etc.), and other search tools that rely on this Spotlight data, like HoudahSpot.

In any case, I was hoping to create a DEVONthink smart rule that I could use to occasionally sync these fields. However, I’ve been completely stumped by how the “Date Last Opened” field works in Finder. From what I can tell, I believe it’s read from Spotlight’s com.apple.metadata:kMDItemLastUsedDate field. But I’ve had no luck trying to write to it using xattr and a few other commands. Does anyone know how to write to that field (or whatever field Finder is actually reading the “Date Last Opened” from)?

To be clear, on the DEVONthink side of things, it’s easy enough to grab the file’s “opening date”; I just need some help understanding how to add or modify an existing “Date Last Opened” in Finder/Spotlight. At this point, I feel like I’ve tried so many different variations of the same Terminal commands that my head is spinning. :man_facepalming:

Thanks in advance for any help you can lend!

As the standard script suites (e.g. Finder, Standard Additions & System Events) don’t seem to support this, the best option is probably to use the foundation framework to read/write NSURLContentAccessDateKey. Here’s a very basic example:

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

return getPathResourceValue("/Users/username/Documents/Filename.ext", current application's NSURLContentAccessDateKey) as date

on getPathResourceValue(thePosixPath, theKey)
	local theURL, theResult, theValue
	set theURL to current application's |NSURL|'s fileURLWithPath:thePosixPath
	set {theResult, theValue, theError} to (theURL's getResourceValue:(reference) forKey:theKey |error|:(reference))
	if theResult as boolean is true then return theValue
	return missing value
end getPathResourceValue
1 Like

Hi @cgrunenberg! Thanks a ton for taking a look at this for me. I really appreciate it.

I don’t have much familiarity with the foundation framework, so I apologize if I’m overlooking something. Is your example script supposed to read the file’s last opened date?

When I run it using a pdf’s file path on my computer, I get a date that does not match what Finder is reporting for the pdf’s “Date Last Opened.” I might be wrong, but the script actually appears to report Script Editor’s last opened date - which is the application I’m running the script from (i.e., after comparing the MDLS output for kMDItemLastUsedDate of both Scrip Editor and the pdf … and then subtracting my timezone from GMT). Am I missing something?

Thanks again for all of your help!

Actually I assumed that this date would match the Finder’s last opened date but the documentation is unfortunately sparse. Now I tried this again using a bunch of fresh downloads (PDF, HTML). No date right after downloading as expected but still no date after opening them in various apps. Meaning neither a date in the Finder nor one returned by the script.

Thanks for taking another look at it @cgrunenberg! I really appreciate it, and thought I was doing something wrong there.

As for the date, I might be wrong, but I still think it comes from the kMDItemLastUsedDate? Finder/Spotlight or some other ghost in the machine appears to be doing the math to convert the date/time to the user’s timezone prior to displaying it in Finder.

For instance, since I’m in the Bay Area - which is 7 hours behind GMT - if I just subtract 7 hours from the kMDItemLastUsedDate, that matches what Finder is displaying as the “Date Last Opened.” Maybe there are exceptions, but I haven’t found any yet.

It’s easy enough to read that value kMDItemLastUsedDate, I just can’t figure out how to write to it? How do other applications do it?

Thanks again!

Did you try

do shell script "touch " & quoted form of thePath

?

I’m not at my mac, but “touch” got a flag that allows to set the date to a given date (the above would set it to the current date).

Search “man page touch”.

Thanks for your help @pete31! Unfortunately, I tried the touch command before posting here, and it doesn’t work either (as is, or with the -mt options and others). From what I read, this approach used to work on old MacOS versions, but stopped working sometime around Catalina (though it might have been prior to that).

Thanks though!

Seems it’s not possible (or I’ve no idea how to do it).

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set thePath to "/Users/user/Desktop/1.md"
set theURL to current application's |NSURL|'s fileURLWithPath:thePath

set {theResult, theError} to theURL's setResourceValue:(current date) forKey:(current application's NSURLContentModificationDateKey) |error|:(reference)
-->  Works: NSURLContentModificationDateKey

set {theResult, theError} to theURL's setResourceValue:(current date) forKey:(current application's NSURLCreationDateKey) |error|:(reference)
--> Works: NSURLCreationDateKey

set {theResult, theError} to theURL's setResourceValue:(current date) forKey:(current application's theNSURLContentAccessDateKey) |error|:(reference)
--> Doesn't work: theNSURLContentAccessDateKey

I then checked the documentation and it says :

When you set the NSURLContentAccessDateKey for a resource, also set NSURLContentModificationDateKey in the same call to the setResourceValues:error: method. Otherwise, the file system may set the NSURLContentAccessDateKey value to the current NSURLContentModificationDateKey value.

So I tried

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set thePath to "/Users/user/Desktop/1.md"
set theURL to current application's |NSURL|'s fileURLWithPath:thePath

set theDate to current date
set {theResult, theError} to theURL's setResourceValues:{NSURLContentAccessDateKey:theNSDate, NSURLContentModificationDateKey:theNSDate} |error|:(reference)
--> Doesn't work

Not sure, but I think what you see with mdls and in Finder is the kMDItemLastUsedDate. And this seems to be Spotlight data which can’t be set directly:

kMDItemLastUsedDate

The date and time that the file was last used. This value is updated automatically by LaunchServices everytime a file is opened by double clicking, or by asking LaunchServices to open a file. A CFDate.

Documentation

There’s also a post by Shane Stanley:

You can’t directly set Spotlight metadata — but you can change the information the Spotlight importer imports. (…)

In theory you can probably change the values and replace the old version. But you may end up causing problems if you just change one value — I can see a UUID in there, as well as a date and some other values. Can I ask why you would want to do that?

So I think it’s not possible.

1 Like

Thanks a ton, @pete31! It looks like you’ve come across a lot of the same materials that I was digging through when trying to make sense of how this worked. I’m sure I’m just being hardheaded here, but there’s got to be a way to update this date.

@cgrunenberg Is there any way that you’d consider updating DEVONthink to work with the LaunchServices tool, so that it updates the last opened date like other apps? Since you guys have continued to improve the way that DEVONthink works with Finder, this feels like a natural progression. It’s also super helpful to maintain this date for other apps that rely on Spotlight metadata, like HoudahSpot, etc. Thanks for your consideration (and help above, looking for a short-term solution).

1 Like

We consider almost every request but currently there are no such plans (as it’s the first request ever of its kind).

2 Likes