Use Current Date to open a document with that file name

I’m trying to write a script that will use the current date (read from the computer) in the form dd/mm/yy to open a file with that name.
For example if today is 05/06/06 the script would open a file with the name “05/06/06”
I can get the current date but can’t go beyond that.

Any ideas?

Applescript’s “month of” modifier for date objects won’t return a numeric month. Instead, it returns “May” or “January”. And if you use “/” in the file spec, Applescript won’t want to make that into a file name. (probably because the slash character, while valid in the Finder, is reserved in unix)

That being said, there are a couple of approaches you can use, depending on what you want to do with the file. If you need a blank Finder document, use:


tell application "Finder"
	set myMonth to month of (current date)
	if (myMonth as string = "May") then set myMonth to "05"
	set myDay to day of (current date)
	if (myDay < 10) then set myDay to "0" & (myDay as string)
	set myYear to characters 3 thru 4 of (year of (current date) as string)
	copy (myMonth & "/" & myDay & "/" & myYear) as Unicode text to myFile
	make new file at (path to current user folder) with properties {name:myFile}
end tell

If you are wanting to open a file within a script so you can write some data to it, the situation is a bit different. This:


set myMonth to month of (current date)
if (myMonth as string = "May") then set myMonth to "05"
set myDay to day of (current date)
if (myDay < 10) then set myDay to "0" & (myDay as string)
set myYear to characters 3 thru 4 of (year of (current date) as string)
copy (myMonth & "/" & myDay & "/" & myYear) as Unicode text to myFile
--Basically the same script down to here
open for access ((path to current user folder) & myFile) as Unicode text with write permission
copy the result to outFile
write "Some data" to outFile
close access outFile

will give you an error because of the slashes in the file name. The simple solution, of course, is to use the Finder file creation and then open that file, like this:


tell application "Finder"
	set myMonth to month of (current date)
	if (myMonth as string = "May") then set myMonth to "05"
	set myDay to day of (current date)
	if (myDay < 10) then set myDay to "0" & (myDay as string)
	set myYear to characters 3 thru 4 of (year of (current date) as string)
	copy (myMonth & "/" & myDay & "/" & myYear) as Unicode text to myFile
	make new file at (path to current user folder) with properties {name:myFile}
	copy the result to myFile
	open for access myFile as Unicode text with write permission
	copy the result to outFile
	write "Some data" to outFile
	close access outFile
end tell

but that will still give you an error.

So, if you want to open the file to be written (or read) you have to use something other than slashes in the name.

Hi, both.

If Galend’s scripting for a pre-X system, which is the proper business of this forum, slashes are perfectly OK in file names ” although obviously he/she would do well to avoid their use in anticipation of a move to OS X. :slight_smile: If the file’s been saved with that name by an application, of course, then there’s no choice.

A brief way to get a slashed, ddmmyy, short-date string from a date is this:

on ddmmyy(theDate)
	-- Get the day and year numbers.
	set {day:d, year:y} to theDate
	
	-- Get the month number using a "French Vanilla" variant.
	copy theDate to b
	set b's month to January
	set m to (b - 2500000 - theDate) div -2500000
	
	-- Combine the results into a yyyymmdd value, coerce
	-- that to string, extract and recombine the relevant bits.	
	tell (y * 10000 + m * 100 + d) as string -- (or as unicode text)
		return text 7 thru 8 & "/" & text 5 thru 6 & "/" & text 3 thru 4
	end tell
end ddmmyy

ddmmyy(current date)
--> "07/05/06" (if run on 7th May 2006)

Galend doesn’t say if the script has to create the file or whether it already exists, or where the file will be, or whether it’s the script or an application that has to deal with it; so at the moment, I’m afraid it’s not possible to offer more help than that.

My bad, of course you’re right, “it was late when I posted” is my only excuse. (“I’m sorry officer, I wasn’t watching where I was driving when I drove up onto the sidewalk and hit that pedestrian.”) :stuck_out_tongue:

For those of us in the US, the month and day would be switched, though (05/07/06 instead of 07/05/06):


on ddmmyy(theDate)
	-- Get the day and year numbers.
	set {day:d, year:y} to theDate
	
	-- Get the month number using a "French Vanilla" variant.
	copy theDate to b
	set b's month to January
	set m to (b - 2500000 - theDate) div -2500000
	
	-- Combine the results into a yyyymmdd value, coerce
	-- that to string, extract and recombine the relevant bits.    
	tell (y * 10000 + m * 100 + d) as string -- (or as unicode text)
		return text 5 thru 6 & "/" & text 7 thru 8 & "/" & text 3 thru 4
	end tell
end ddmmyy

Not all Americans use that format! However, it is good to point out that it can be easily changed. :slight_smile:

Hi Bruce! :smiley:

I didn’t know that! You learn something new every day (if you’re paying attention, that is).

Ideally, you would want to use the format that the user selected in their Date and Time control panel, but it appears that control panel doesn’t have a dictionary.

Thanks all. This is for an OS 9.2 system. The files already exist. For example there is a file named “05/07/06”. I want the script as a startup item which will read the current date and open the file with that dates name. I think the info you gave me will work. I’ll let you know.

I didn’t know that! Interesting. Thanks, Bruce.

I think you probably have to impose your own style (separators, long or short year numbers, etc.), but you can observe the user’s preferred order like this:

on shortdate(theDate)
	-- Get a yyyymmdd shortdate string (without separators) for theDate.
	set {day:d, year:y} to theDate
	copy theDate to b
	set b's month to January
	set m to (b - 2500000 - theDate) div -2500000
	set yyyymmdd to (y * 10000 + m * 100 + d) as string
	
	-- Create indices from the day, month, and year numbers of 'date "1/2/3",
	-- which will be interpreted according to the user's date/time settings.
	-- The indices reflect what comes 1st, 2nd, & 3rd in the user's shortdate order.
	set {day:dIndex, year:yIndex} to date ("1/2/3" as string)
	set yIndex to yIndex mod 10 -- Last digit only.
	set mIndex to 6 - dIndex - yIndex
	
	-- Use the indices to order the yyyymmdd details in a list.
	set sDate to {missing value, missing value, missing value}
	set item dIndex of sDate to text 7 thru 8 of yyyymmdd
	set item mIndex of sDate to text 5 thru 6 of yyyymmdd
	set item yIndex of sDate to text 3 thru 4 of yyyymmdd
	
	-- Coerce the list to string, with the required separators.
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set sDate to sDate as string
	set AppleScript's text item delimiters to astid
	
	return sDate
end shortdate

shortdate(current date)
--> "07/05/06" (for 7th May 2006 on my machine).

:cool:

Will these scripts work for ANY month? The value 2500000 works out to about 30 days, but won’t it be off for longer months?

The way I read this:

   set b's month to January
   set m to (b - 2500000 - theDate) div -2500000

is:

Take the date and reset it’s month to 1
subtract the number of seconds in a month
subtract the original date
(this should give you the negative value for the current month)
then divide by the negative of the number of seconds in a month

I’m just wondering if there isn’t some small error introduced that will pop up at some point?

Hi, Kevin.

Yes. There’s plenty of slack for it to work with any month. But the idea takes a little getting used to! It works with any number of seconds between 28 days and about 29.5 days. 2500000 is a number in that range that happens to be easy to remember.

I actually explained the principle of this method last week in the bottom (fifth) post of this thread. The double negative is a bit confusing. It’s to get round a bug that existed in AppleScript’s internal date math routines before OS X Tiger. (It may have been fixed in Panther, but I didn’t get that, so I don’t know.) The bug was that if you subtracted one date from another, and they were both earlier than 1904, then the system threw an error. (Obviously, this bug wasn’t encountered very often!) However, it didn’t occur if a later pre-1904 date was subtracted from an earlier one ” only if the earlier one was subtracted from the later, or if the dates were the same.

Richard Hartman’s version of Emmanuel’s “French Vanilla” method looked like this:

copy theDate to b
set b's month to January
set m to 1 + (theDate - b) div 2500000

The logic of the last line is easier to follow here:

  1. Subtract the January date from the date being tested. Since the two dates have the same year, day, and time, the result is exactly the same as the number of seconds from the beginning of the year to the beginning of the month whose number we want.
  2. Divide the result by a number in the range that works and discard the remainder. There’s enough headroom and floor-room to ensure that the result is the same as the number of calendar months that precede the tested month in the year and that any inaccuracies are discarded with the remainder.
  3. Add 1 to get the number of the tested month itself.

This works well enough for most reasonable purposes, but will error on earlier systems if the test date is earlier than 1904. Obviously, this is because the January date will also be earlier than 1904 and will be earlier than, or the same as, the test date. My own last line is a rearrangement of the maths to get round the bug.

set m to (b - 2500000 - theDate) div -2500000

Subtracting 2500000 before a division by -2500000 adds an extra 1 to the result and so is equivalent to the added 1 in the original last line. Here, it’s subtracted from the January date first, so that even if theDate is a January date itself, it’ll be subtracted from a date that’s earlier than it, thus avoiding the bug. This leaves a negative number of seconds which, when divided by a negative divisor, gives a positive result.

The object of the exercise when these routines were written was to get them to be as fast as possible by keeping the number of operations to a minimum. My last line has the same number of mathematical steps as Richard’s original, but is two date subtractions and an integer division, as opposed to the original’s one date subtraction and two integer operations. Mine is therefore probably a nanosecond or two slower. :wink:

I’ll be honest, I (was) a math major and some of what you’re doing LOOKS like hocus pocus, but when I take the time to pull it all apart it makes sense.

I guess I’m more of a “text” thinker when it comes to applescript. My solution to this would have been:

display dialog shortDate(current date)

to shortDate(theDate)
	set monthList to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
	
	set mm to 1
	repeat while (month of theDate) as string ≠ (item mm of monthList) as string
		copy mm + 1 to mm
	end repeat
	if mm < 10 then copy "0" & mm to mm
	
	set dd to day of theDate
	if dd < 10 then copy "0" & dd to dd
	
	set yy to text 3 thru 4 of ((year of (theDate)) as string)
	
	if second word of (date ("1/2/3" as string) as string) is "January" then
		return mm & "/" & dd & "/" & yy
	else
		return dd & "/" & mm & "/" & yy
	end if
end shortDate

Though I did like your way of discerning the proper date format, and made use of my own altered form of it.

Yes. The thinking behind it is a mixture of maths, program efficiency, and AppleScript peculiarities. :slight_smile:

Yes. I noticed that. :slight_smile: For instance, your monthList contains the strings “January”, “February”, etc., instead of the AppleScript month constants January, February, etc. Strings take longer to compare than do month constants and you have the added work of coercing theDate’s month constant to string first. (What you do on your own machine is, of course, entirely up to you, so please take my comments in that context.)

“French Vanilla” was designed to dispense with the need for a repeat loop; but if you’re going to use one, there are things you can do to make it more efficient. They won’t make a noticeable difference in this context, but they’re good principles to keep in mind.

display dialog shortDate(current date)

to shortDate(theDate)
	-- Use month constants instead of strings.
	set monthList to {January, February, March, April, May, June, July, August, September, October, November, December}
	
	set mm to 1
	-- Extract the month constant from theDate only once, before the repeat.
	set theMonth to month of theDate
	-- Test positively rather than negatively, if possible. (Very esoteric, this one!)
	repeat until (theMonth = item mm of monthList)
		-- Use 'set' rather than 'copy', unless you really need to duplicate the data.
		set mm to mm + 1
	end repeat
	if (mm < 10) then set mm to "0" & mm
	
	set dd to day of theDate
	if (dd < 10) then set dd to "0" & dd
	
	-- Notice here that if either dd or mm is greater than 9,
	-- it'll still be an integer, not a string. An explicit coercion is
	-- needed below to ensure that a string is returned, not a list!
	
	set yy to text 3 thru 4 of ((year of (theDate)) as string)
	
	-- 'if second word of (date ("1/2/3" as string) as string) is "January" then'
	-- is only reliable on systems where the long date is in English, the weekday
	-- is included and comes first, and the year comes last. It's more internationally
	-- applicable and more efficient to use the month constant. But this still won't
	-- be right if the user's machine is configured for yyyymmdd short dates.
	if (month of (date ("1/2/3" as string)) is January) then
		-- dd and mm could be either strings or integers.
		-- Explicitly coerce the first one to string
		-- to ensure the desired concatenation result.
		return (mm as string) & "/" & dd & "/" & yy
	else
		return (dd as string) & "/" & mm & "/" & yy
	end if
end shortDate

With all the implicit coercions in applescript, doesn’t it seem odd that Apple missed allowing for
a) a short date format
and
b) the month constants to be equal to their numeric equivalents? (i.e. “if january = “1” then…”)

I thought I had it - well shucks. This question is easy - I’m just a dumb biologist. After I get the date (ddmmyy) I want to use that to open a file that already exists by that name. I can’t seem to get the syntax.

What I have so far is OK but I can’t seem to get the date string in as the file name. Any ideas?

SAMPLE

on ddmmyy(theDate)
– Get the day and year numbers.
set {day:d, year:y} to theDate

-- Get the month number using a "French Vanilla" variant.
copy theDate to b
set b's month to January
set m to (b - 2500000 - theDate) div -2500000

-- Combine the results into a yyyymmdd value, coerce
-- that to string, extract and recombine the relevant bits.    
tell (y * 10000 + m * 100 + d) as string -- (or as unicode text)
	return text 5 thru 6 & "/" & text 7 thru 8 & "/" & text 3 thru 4
end tell

end ddmmyy
tell application “Finder”
activate
select file "AppleWorks "
open selection
“X” = (text 5 thru 6 & “/” & text 7 thru 8 & “/” & text 3 thru 4)
select file (X) of folder “Universal Calendar 06”
end tell
ddmmyy(current date)
→ “07/05/06” (if run on 7th May 2006)
tell application “Finder”
activate
select file"AppleWorks "
open selection
select file (WITH THE NAME DDMMYY as the string generated above)of folder"2006"of folder “Calendar”
open selection
end tell

It’s a bit late, but it’s been allowed for since Panther, I think, observing the user’s preferences.

short date string of (current date)
--> "08/05/2006" on my machine

Ditto, although the equivalent is an integer rather than a numeric string.

January as integer
--> 1

January as integer as string
--> "1"

(January) + 1
--> 2

Hi, Galend.

Don’t worry about being a biologist. It could happen to anyone. :wink:

  1. Is the file with the shortdate name supposed to be opened in AppleWorks? If so, It would be better to tell AppleWorks to open it rather than telling the Finder.

  2. If you want to set a variable X to the shortdate string, you use the keyword ‘set’ and don’t put quotes round the X. Also, in this case, you need to set it to the result of the ddmmyy() handler.

  3. The ddmmyy() handler you’ve used is Kevin’s version, which returns an mmddyy format. I’ve assumed below that that’s a mistake, since you originally asked for ddmmyy.

  4. ‘file X of folder “2006” of folder “Calendar”’ is a Finder reference. It will need to be changed to an alias for AppleWorks to understand it. If “Calendar” isn’t the name of an attached disk, the Finder would assume that folder “Calendar” was on the desktop. That’s what I’ve assumed here:

on ddmmyy(theDate)
	-- Get the day and year numbers.
	set {day:d, year:y} to theDate
	
	-- Get the month number using a "French Vanilla" variant.
	copy theDate to b
	set b's month to January
	set m to (b - 2500000 - theDate) div -2500000
	
	-- Combine the results into a yyyymmdd value, coerce
	-- that to string, extract and recombine the relevant bits.    
	tell (y * 10000 + m * 100 + d) as string -- (or as unicode text)
		return text 7 thru 8 & "/" & text 5 thru 6 & "/" & text 3 thru 4
	end tell
end ddmmyy

-- Set X to the shortdate string for today.
set X to ddmmyy(current date)
-- Get a path to file X in folder "2006" in folder "Calendar" on the desktop.
set Xpath to (path to desktop as Unicode text) & "Calendar:2006:" & X

-- Open the file in AppleWorks.
tell application "AppleWorks"
	activate
	open alias Xpath
end tell

I don’t have AppleWorks with which to test this, but it should work. It’ll error if the file doesn’t exist at that location.

For some reason, AppleWorks seems to not like filenames with slashes in them. Not sure why, but running the script below works ONLY if you tell the Finder to open the document, not AW. AW will not save a file with slashes in the name, either, so it must be an oddity of AW.

Also, AW saves it’s files with the “.cwk” extension, whether you see it or not, and you have to take that into account when specifying the file. The script posted below works for me, try it and see if it is what you need.

set myDoc to shortDate(current date)
set myDoc to ((path to desktop) & myDoc & ".cwk") as Unicode text
tell application "Finder"
	open myDoc
end tell

to shortDate(theDate)
	set monthList to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
	
	set mm to 1
	repeat while (month of theDate) as string ≠ (item mm of monthList) as string
		copy mm + 1 to mm
	end repeat
	if mm < 10 then copy "0" & mm to mm
	
	set dd to day of theDate
	if dd < 10 then copy "0" & dd to dd
	
	set yy to text 3 thru 4 of ((year of (theDate)) as string)
	
	if second word of (date ("1/2/3" as string) as string) is "January" then
		return mm & "/" & dd & "/" & yy
	else
		return dd & "/" & mm & "/" & yy
	end if
end shortDate

Hi, Kevin.

Don’t forget Galend’s using an OS 9.2 system. (Message #7 in this thread.) File extensions can’t be hidden there. If you don’t see them, they don’t exist.

In your script, the value of ‘myDoc’ is a piece of Unicode text, not an alias or file specification. That may be why AppleWorks won’t open it. Have you tried this?

set myDoc to ((path to desktop as Unicode text) & myDoc & ".cwk" ) as alias

Also, I don’t know if you saw my comments about your shortDate() handler yesterday. (Message #12 above). From tomorrow in the UK and elsewhere, and from October in the US, it’ll return a list instead of a string.

Yes, I’m no whiz at OS 9 programming anymore. And I keep forgetting that we’re dealing with 9 here.

I tried using “as alias” or specifying “file” before the path, neither one worked for AW running in Jaguar. Kept getting a -1700 error in AW before I switched to unicode.

Yes, I hadn’t thought of that. Suppose I would have bumped into it eventually and had to fix it. Did I mention I have been away from AS for a while? :wink:

Me again. I think I’ll stick to being a biologist. First the AppleScript version is 1.1.3. Also, this isn’t my computer. I though it was running OS 9.2. Nope - it’s 8.5.1.

When I try to run the script it gets to this line:

repeat while (month of theDate) as string ≠(item mm of monthList) as string
copy mm + 1 to mm
end repeat

and then I get an Execution Error "Can’t make “May” into a string. Also I don’t think this version will let me set myDoc as unicode text.

Still trying.