OK, the following code works perfectly in Tiger & Leopard, I can only conclude that either the feature that allows this was missing in Panther or is broken. Any solutions would be wonderful.
I am calculating the difference between Date Stamps (in UNIX epoch format)
Like so:
set stamp1 to do shell script "/bin/date +%s"
set stamp2 to do shell script "/usr/bin/defaults read /Library/Preferences/com.myapp.app checkInStamp"
set theInterval to stamp2 - stamp1
if theInterval is less than 21600 then
runTheHandler()
end if
However, this fails in Panther, with the following error:
“can’t make 1221685224 into a number”
So, I tried the following:
set stamp1 to do shell script "/bin/date +%s"
set stamp2 to do shell script "/usr/bin/defaults read /Library/Preferences/com.myapp.app checkInStamp"
set theInterval to do shell script "/bin/echo '$((" & stamp1 & "-" & stamp2 & "))'"
if theInterval is less than 21600 then
runTheHandler()
end if
This results in a string that greater than or less than comparisons cannot use. Attempting to coerce it into a number results in “Can’t make [the value] into type number.”
shell scripts return always text, not numbers.
It’s strongly recommended to coerce the values to the required class, although AppleScript coerces often values implicitly
If you want to do math, work with numbers, in this case even with integers
Try this
set stamp1 to do shell script "/bin/date +%s" as integer
set stamp2 to do shell script "/usr/bin/defaults read /Library/Preferences/com.myapp.app checkInStamp" as integer
set theInterval to stamp2 - stamp1
if theInterval is less than 21600 then
runTheHandler()
end if
Stefan, thanks for responding, but your suggestion doesn’t work for me – here’s what happens under Mac OS X 10.3:
set stamp1 to do shell script "date +%s" as integer
set stampa to do shell script "date +%s"
set stamp2 to do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp" as integer
set stampb to do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp"
set theInterval to stamp2 - stamp1
set theInterval2 to stampb - stampa
--from "Event Log"
tell current application
do shell script "date +%s" as integer
8.25373233E+8
do shell script "date +%s"
"1221697683"
do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp" as integer
8.25373233E+8
do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp"
"1221684730"
"Can't make \"1221684730\" into a number."
Can you see my problem now?
Even though the values are actually different, AppleScript converts them to the Same value as integers.
Something is definitely not right.
The error’s coming from your attempt to subtract stampa from stampb. The two subtractions don’t show in the Event Log because they’re vanilla AppleScript, but the error from the second one does.
If as integer doesn’t work (as it sometimes doesn’t on my Jaguar machine), try the more generic as number.
In Jaguar and Tiger, the value given to theInterval is the “$((-))” expression. To make it the result of the expression (a numeric value as Unicode text) you need to leave out the single quotes:
set theInterval to do shell script "/bin/echo $((" & stamp1 & "-" & stamp2 & "))"
You then need to coerce the numeric text to an AppleScript number for the is less than line ” otherwise, with numeric text on the left and a number on the right, the number will be coerced to text and the two will be compared lexicographically instead of numerically. Alternatively, of course, you could use is greater than and have the number on the left and the numeric text on the right:
if 21600 is greater than theInterval then runTheHandler()
Just out of curiosity, does this one-liner work for you?
if (21600.0 > (do shell script "/bin/echo $(($(/bin/date +%s)-$(/usr/bin/defaults read /Library/Preferences/com.myapp.app checkInStamp)))")) then runTheHandler()
that was just for illustration purposes. I’m not concerned about the error - it was just to show that stamp was actually a different value when read as a string v. an integer, and that AppleScript converted two strings to the same integer, making the calculation of the interval impossible. I’m aware of the error - however, substracting stampa from stampb works perfectly in 10.4 and 10.5. Attempts to coerce those UNIX times stamps to integers are failing. If you look closely at the code I posted, you’ll see that both integers are the same - this has to be a bug, I need a workaround, cause we ain’t gonna get no bug fixes for Mac OS X 10.3, that’s for sure!
set stamp1 to do shell script "date +%s" as number
set stamp2 to do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp" as number
set theInterval to stamp2 - stamp1
--Event Log
tell current application
do shell script "date +%s" as number
«data nmbr31323231373031313339»
do shell script "/usr/bin/defaults read /Library/Preferences/AutoHelpMate checkInStamp" as number
«data nmbr31323231363834373330»
"Can't make «data nmbr31323231363834373330» into a number."
AppleScript doesn’t like the number for whatever reason. Can’t figure it out. Have spent all day working on the problem, but am stumped right now.
Right. I’ve managed to duplicate that on my 10.4 machine. There seems to be a confusion about exactly what’s to be coerced to number. Cure: separate the shell script calls from the coercions with parentheses:
set stamp1 to (do shell script "date +%s") as number -- or possibly 'as integer' now!
I’m off to bed now, as it’s nearly three o’clock in the morning here. I’ll check back when I get up.
apparently the timestamp in seconds (as someone was kind enough to point out on the Apple Listserv) produces a number or integer that is too large for AppleScript under 10.3 to use to perform calculations. I simply divided it by 60, and my script is very happy now.
It turns out to be because, since OS 10.3, do shell script has an as parameter, which determines how do shell script interprets the shell script result before returning its own result as a type that AppleScript understands. Unix commands usually return ASCII text, so, by default, do shell script interprets the results as such and returns the equivalent AppleScript Unicode text to the script.
The Unix “date +%s” result “1221701139” is a string of ten bytes whose values are the ASCII numbers of the individual characters. If do shell script gets this while its as parameter is integer, it interprets the first four bytes as a four-byte integer instead of as four one-byte characters ” and that’s what it returns to the script. You get the same result each time because the four leftmost digits only change slowly over the years. To demonstrate the effect:
do shell script "/bin/echo 1221" as integer
--> 8.25373233 (The result you were getting.)
In the case of as number, I presume that do shell script itself doesn’t understand that particular AppleScript class and so returns a data object of type nmbr rather than a «class nmbr» object. («class nmbr» is the AppleScript class code corresponding to its keyword number.) The numbers you see in the Result or Event Log panes are the byte values in hexadecimal notation.
do shell script "/bin/echo 1221" as number
--> «data nmbr31323231»
Using parentheses, as I suggested last night, allows do shell script to interpret the Unix result correctly as a string and to return the equivalent AppleScript Unicode text. AppleScript itself then coerces the Unicode text to its class integer or class number.
(do shell script "/bin/echo 1221") as number
--> 1221
PS. I’m glad you’ve found a solution overnight to the problem. I skipped 10.3 and am not familiar with its vagaries. But since the syntax you were using is intrinsically wrong, it’s still worth considering the points raised here.
Well, that’s not exactly the case, because I know about the parentheses and about coercion- believe me, I know - and tried just about every combination of what you suggested and more before I posted. The examples I posted were to illustrate the success of a mathematical operation that succeeded on 10.4 and 10.5 but failed on 10.3. Luckily, someone on the Apple Listserv gave me the benefit of the doubt and presumed that I new about coercion, etc, and got right to the heart of the issue which led to the solution. Here was his response to the original post in this thread:
“do shell script always returns strings. Whether or not you can use them directly as integers as above in your calculations will depend on the AppleScript integer limit size and coercion order.”
He hit the nail on the head with the “AppleScript integer limit size” - so when divided by 60 (seconds to minutes) the mathematical operations work as expected in Panther. It’s hard sometimes to get at the heart of the problem if you haven’t encountered it, and sometimes it’s hard to post to a forum in such a way that will let people see the issue, rather than the code that surrounds it - but I do appreciate your effort. It’s probably my fault for not making it clear enough what the issue was.