Setting creation date fails (Bug?)

Hi, I’m extracting the year and month a record was published from its name and want to set its creation date to those and the day to 1.

However I get unexpected results, as

  • the day is set to 3 (instead of 1)
  • the time changes (without changing this at all)

Here’s a screenshot

2019-11-05_00-44-17

What I want the selected record’s creation date to be is 01.05.12, 10:39. (The time is not important, just curious how it can change whithout telling it to do so.)

Here’s the script

tell application id "DNtp"
	try
		set windowClass to class of window 1
		if {viewer window, search window} contains windowClass then
			set currentRecord_s to selection of window 1
		else if windowClass = document window then
			set currentRecord_s to content record of window 1 as list
		end if
		
		repeat with thisRecord in currentRecord_s
			set theName to name of thisRecord
			set theCreationDate to creation date of thisRecord
			set theCreationDate's year to (characters -8 thru -7 in theName as string)
			set theCreationDate's month to (characters -6 thru -5 in theName as string)
			set theCreationDate's day to 1
			set creation date of thisRecord to theCreationDate
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

What am I missing? Or is this a bug?

This seems to be a bug of date scripting:

set theName to "aben1205"

-- Fails
set theCreationDate to current date
set theCreationDate's year to (characters 5 thru 6 in theName as string)
set theCreationDate's month to (characters 7 thru 8 in theName as string)
set theCreationDate's day to 1

-- Works
set theCreationDate to date ("1/" & (characters 7 thru 8 in theName as string) & "/20" & (characters 5 thru 6 in theName as string))

I don’t think this qualifies as a bug. A 2-digit year is ambiguous, so AppleScript requires a 4-digit number for the year.

I strongly suggest using only the 1st method when modifying a date object. The other form, with separator included, may fail when the system’s settings are different.
So:

set theCreationDate’s year to (“20” & characters 5 thru 6 in theName as string)

The year isn’t the issue, the day isn’t set as expected in the first part of the example.

Yes, missed that - sorry.
But it does not error here (10.11). He doesn’t mention his OS version, or the actual day he tried the code first.
Anyway, there’s a bug in that date setting code…
When current date is 31 aug, and you are setting the month to feb, it rolls over into march, and the final result is 1 mar, not 1 feb. Always first set the day to 1, then change the other properties. Then set the required day last.

Thanks for the hint! However, at least today this shouldn’t matter.

Thanks, got it. But what I don’t understand is why you can use

inside a DEVONthink tell block. Over here it’s not possible to compile it when used this way so I used a handler. Is this necessary or am i missing something?

tell application id "DNtp"
	try
		set windowClass to class of window 1
		if {viewer window, search window} contains windowClass then
			set currentRecord_s to selection of window 1
		else if windowClass = document window then
			set currentRecord_s to content record of window 1 as list
		end if
		
		repeat with thisRecord in currentRecord_s
			set theName to name of thisRecord
			set theYear to "20" & characters -8 thru -7 in theName as string
			set theMonth to characters -6 thru -5 in theName as string
			set theDay to "1" as string
			set theDate to my makeDate(theDay, theMonth, theYear)
			set creation date of thisRecord to theDate
		end repeat

	end try
end tell

on makeDate(theDay, theMonth, theYear)
	set theDate to date (theDay & "." & theMonth & "." & theYear & ".")
end makeDate

My example was generic and not for DEVONthink, therefore a handler might indeed be necessary.

Bringing this back up. I have about 1000 records that set a creation date of either 12/31/1969 or 01/03/1903 on import. The file names start with the syntax of “yyyy.mm.dd -” (2018.06.15). I’d like to use change the creation date to 06/15/2018. When I run the following script, I get an error on an invalid searchString. Any suggestions to fix that would be appreciated


tell application id "DNtp"
	try
		set windowClass to class of window 1
		if {viewer window, search window} contains windowClass then
			set currentRecord_s to selection of window 1
		else if windowClass = document window then
			set currentRecord_s to content record of window 1 as list
		end if
		
		repeat with thisRecord in currentRecord_s
			set theName to name of thisRecord
			set theYear to characters -1 thru -4 in theName as string
			set theMonth to characters -6 thru -7 in theName as string
			set theDay to characters -9 thru -10 in theName as string
			set theDate to my makeDate(theMonth, theDay, theYear)
			set creation date of thisRecord to theDate
		end repeat
		
	end try
end tell

on makeDate(theMonth, theDay, theYear)
	set theDate to date (theMonth & "." & theDay & "." & theYear & ".")
end makeDate

I can’t test these ideas just now, but:

  • I would be using characters 1 thru 4 rather than negative numbers
  • there is a superfluous & ”.” at the end of the line in your subroutine
  • I would end the subroutine with return theDate

If that doesn’t work, I would simplify the first section to set currentRecord_s to the selection to better determine in which routine the error is occurring (and/or use the Replies section in ScriptEditor).

1 Like

The error is resulting from the term search window; this is the reply which Script Editor gives:

tell application “DEVONthink 3”
get class of window 1
viewer window
search window
error “Invalid argument searchString” number -50
end tell

search is being interpreted as a command rather than a window descriptor. Available descriptors according to the dictionary are document window, think window, viewer window and window.

To expand on what I wrote earlier: the superfluous & "." doesn’t have any negative effect in my testing; return is not required in the subroutine; as expected though, negative digits for the characters command don’t work (that is assuming what you wrote initially, namely that the file names start with the date in the format provided, is correct).

(For anybody passing: characters -1 thru -4 of “1234567890” are “7, 8, 9, 0”, whereas characters 1 thru 4 are “1, 2, 3, 4”).

As a rule, I don’t add the try/end try routine until I have debugged my scripts; they fail silently otherwise.

2 Likes

That’s a quite old way to do it. And because search window is DEVONthink 2 syntax and DEVONthink 3 at some point started to check for invalide syntax this won’t work anymore.

You can simply replace this whole block with

set currentRecord_s to selected records

And I would suggest to replace variable currentRecord_s with theRecords (no idea why I used currentRecord_s back then).

Batch processing or a smart rule should be able to handle this too:

Or if you want to use a script:

tell application id "DNtp"
	repeat with thisRecord in selected records
		set theName to name of thisRecord
		set theYear to characters 1 thru 4 in theName as string
		set theMonth to characters 6 thru 7 in theName as string
		set theDay to characters 9 thru 10 in theName as string
		set theDate to my makeDate(theMonth, theDay, theYear)
		set creation date of thisRecord to theDate
	end repeat
end tell

on makeDate(theMonth, theDay, theYear)
	-- The expected format depends on the system settings
	local theDate
	try
		-- Try DD.MM.YYYY
		set theDate to date ((theDay & "." & theMonth & "." & theYear) as string)
		if exists theDate and theDate is not missing value then return theDate
	on error
		-- Use MM/DD/YYYY
		return date ((theMonth & "/" & theDay & "/" & theYear) as string)
	end try
end makeDate
1 Like

From the obfuscated JavaScript code department:

const app = Application("DEVONthink 3");
app.selectedRecords.forEach(rec => {
  try {
    const date = new Date(r.name().replace(/^\(\d{4}).(\d\d).(\d\d)/,"$1-$2-$3"));
    r.creationDate = date;
  } catch (e) {
    app.logMessage(e);
  }
})

Not tested, as usual. Just a show-off for the usage of regular expressions etc.

Thank you all - off to make it work

This worked like a charm - thanks again

1 Like