Help with date and time script

Ok the idea of this script is to

  1. Run at random times of the day
  2. Keep running for a number of weeks
  3. Make a recording from the line-in for a set time each time

My biggest problem is the “getTimesForToday” & “getATime” subroutines.
in particular the line

		if timeList does not contain tempTime then 

seems to always answer true no matter what. Is this the correct syntax for saying “if a item doesnt exist in the list then do stuff”??

the basic idea in my code is thus:
May be of some use to someone out there if I can get it working!
(the audio recorder app I use can be found here )


property timeList : {}
property numTimesaDay : 10
property currTime : numTimesaDay -- set it to the same so when first callled gets set up
property secondsToRecord : 2 -- number of seconds to record
property possHours : {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
property possMinutes : {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55}

-- MAIN:
on idle
	try
		log ("started")
		
		set nowTime to do shell script "date +%H:%M"
		log ("time Now: " & nowTime)
		
		-- Is TimeList position at the end?
		--if nowTime is "00:01" then
		if currTime ? numTimesaDay then
			-- Get the times for today 
			-- Stores the times in the timeList global
			getTimesForToday()
			display dialog ("got times for today!")
			set currTime to 0
		end if
		
		-- Ok would now have timeList lets see if the current time is in the array
		if timeList contains nowTime then
			display dialog ("recording!")
			set filename to do shell script "date +%x_" & currTime & "%H_%M" & ".mp3"
			doRecord(filename)
			currTime + 1
		end if
		
	on error errStr number errorNumber
		display dialog (errStr)
	end try
	return 60
end idle


-- On QUIT
on quit
	display dialog �
		"Really quit?" buttons {"No", "Quit"} default button "Quit"
	if the button returned of the result is "Quit" then
		continue quit
	end if
	-- Without the continue statement, the 
	-- script application doesn't quit. 
end quit


on doRecord(filename)
	-- The actual script that does the record
	tell application "Audio Recorder"
		set the output format to MP3
		set the quality to custom
		set the MP3 bit rate to 32
		set the MP3 mode to mono
		
		set the next file name to filename
		start recording
		delay secondsToRecord
		stop recording
	end tell
end doRecord

-- This runs once a day to get the times it will run
on getTimesForToday()
	-- note may break for 7,8,9 because should be 07,08,09
	repeat with n from 1 to numTimesaDay
		set tempTime to getATime()
		log ("time " & n & " ->" & tempTime)
		copy tempTime to the end of timeList
	end repeat
end getTimesForToday


-- gets a Time that isnt in the list
on getATime()
	set uniqTimeFound to false
	
	repeat until uniqTimeFound
		set tempHour to some item of possHours
		set tempMinute to some item of possMinutes
		set tempTime to tempHour & ":" & tempMinute
		
		if timeList does not contain tempTime then
			set uniqTimeFound to true
		end if
	end repeat
	
	return tempTime
	
end getATime


In getATime(), you’re setting tempTime by concatenating together a number, a string, and another number. The result of this is a list, say {12, “:”, 45}. getTimesForToday() then copies this list to the end of timeList, so that timeList is {{12, “:”, 45}}.

Officially, when you test if a list contains an item, you’re supposed to present the item itself in a list:

{1, 2, 3, 4, 5} contains {3}
--> true

AppleScript usually lets you get away without the list wrapper:

{1, 2, 3, 4, 5} contains 3
--> true

But when the item’s a list or a record, you must use the wrapper:

{{12, ":", 45}, {7, ":", 30}} contains {{12, ":", 45}}
--> true
{{12, ":", 45}, {7, ":", 30}} contains {12, ":", 45}
--> false

That’s why you’re always getting ‘true’ for timeList not containing tempTime. The test should be:

if timeList does not contain {tempTime} then

But presumably, you don’t mean tempTime to be a list but a string. You can achieve this by defining all the items in possHours and possMinutes as strings, or you can set tempTime in getATime() like this:

set tempTime to (tempHour as string) & ":" & tempMinute
--> "12:45"

You can then use the wrapper round ‘tempTime’ or not and the test will still produce the right results.

I’ve haven’t checked anything else in the script as I’m not currently in OS X. :slight_smile:

Hi,

In your other subroutine, you use a key word as a variable and ‘next file name’ should be ‘next filename’ I think. I haven’t run it yet but, maybe it should look like this:

on doRecord(the_filename) – changed filename to the_filename
– The actual script that does the record
tell application “Audio Recorder”
set the output format to MP3
set the quality to custom
set the MP3 bit rate to 32
set the MP3 mode to mono

	set the next filename to the_filename -- changed next file name to next filename
	-- also changed filename to the_filename
	start recording
	delay secondsToRecord
	stop (recording)
end tell

end doRecord

gl,

Thats excellent. Thanks to you both.

Still not running as a standalone app but Im nearly there now! thanks

One thing I realised a while ago was that doing the if logic wont work because im checking the time e.g 09:50 against applescripts numbers which get set to 9:5
the simplest way is to remove leading zeros from my

set nowTime to do shell script "date +%H:%M"

any simple way to rid of leading zeros from a string? (or even force applescript to use 2decimal places)

will

Hi,

Personally, I wouldn’t do this with the do shell script. Here’s a little test:

– compares AppleScript time and shell time
set tick1 to the ticks
repeat 100 times
set cur_date to (current date) - 0 * minutes – subtract minutes here for testing
set time_secs to (time of cur_date)
set the_hrs to (time_secs div hours)
set the_rem to (time_secs mod hours) – remeaining seconds
set the_mins to (the_rem div minutes)
– set the_mins to (text -2 thru -1 of (“0” & the_mins)) – to add leading zero
– or
– if length of (the_mins as string) is 1 then set the_mins to “0” & the_mins
set the_time to (the_hrs & “:” & the_mins) as string
end repeat
set tick2 to the ticks
set dif1 to tick2 - tick1

set tick1 to the ticks
repeat 100 times
do shell script “date +%H:%M”
end repeat
set tick2 to the ticks
set dif2 to tick2 - tick1

display dialog {dif1, “:”, dif2} as string
the_time

If you look at the comments in the first section (AppleScript time), then you’ll see a little commented section that show how you can add leading zero. There may be other ways, but I thought this was interesting when someone posted this method. Here’s another script that shows how you can just get the hours and minutes.

set cur_date to (current date)
set time_string to (time string of cur_date)
tell time_string
set my_time to word 1 & “:” & word 2 & space & word 4
end tell

With this method, you must think about military time with the pm and am. if pm, then add 12 to the hours.

Just some examples.

BTW, interesting idea with the recording. It’s a good tutorial. There’s some other stuff in there that needs fixing. Note that you’ll get the same list everyday. You might change the beginning of the script. Save the last date the script was run and compare it with the current date. Then, get a new list if the dates are different.

gl,

I can’t see why you’re using text in the first place. Except when you construct the file name, most of the time work is just checking to see if a certain time is in the list. Why not just use numbers - for instance, the number of minutes since midnight? Numbers are faster than text, ‘current date’ is much faster than ‘do shell script’, and you don’t have to faff around with leading zeros.

In your idle handler:

set nowTime to (time of (current date)) div minutes

Then your getATime() handler would be:

on getATime()
  set uniqTimeFound to false
 
  repeat until uniqTimeFound
    set tempHour to (some item of possHours) * 60
    set tempMinute to some item of possMinutes
    set tempTime to tempHour + tempMinute
   
    if timeList does not contain tempTime then
      set uniqTimeFound to true
    end if
  end repeat
 
  return tempTime
 
end getATime

Yep, that’s what I was thinking too because he already has the numbers in the list. One thing I was thinking is that time manipulation may seem hard in the beginning. But, later on it’s very easy after playing around with it a few times. The shell method looks simple.

Hi, Kel.

I only had time to speed-read your post last night when I logged on to post my own reply. (I’m on a dial-up connection to the Internet.)

There’s a problem with this approach in that it’s user-preference specific. The format of ‘time string’, like those of ‘date string’ and ‘someDate as string’, reflects the user’s Date & Time preferences. For instance, my own machine is set up to display the time in 24-hour format with leading zeros on the hours. There’s therefore no ‘word 4’ in the result when I use ‘time string’. Another point - as I discovered recently to my embarrassment - is that the definition of a ‘word’ can vary between system nationalities and between plain text and Unicode text. I don’t know if that would necessarily be a problem here, but - you know - “once bitten …”

If you want to impose a format (without resorting to a shell script), it’s probably safer to write your own routine using the numbers:

set t to time of (current date)

-- Both of the following give leading zeros where required with the minutes
-- 24-hour format with leading zero on the hour
tell (10000 + t div hours * 100 + t mod hours div minutes) as string
  set my_time to text 2 thru 3 & ":" & text 4 thru 5
end tell

-- 12-hour format without
tell (((t div hours + 11) mod 12 + 1) * 100 + t mod hours div minutes) as string
  set my_time to text 1 thru -3 & ":" & text -2 thru -1 & item (t div hours div 12 + 1) of {" am", " pm"}
end tell

I quite agree. Many people who’ve grown up with Unix find the shell method simpler, but AppleScript time and date code is more flexible and executes far more quickly. I also find it more fun than having to memorise cryptic ‘%’ parameters. :wink:

Hi Nigel,

Thanks for pointing that out. I didn’t think about the 24 hour clock. Perhaps an error handler in there could catch the word 4. Personally, I like working with the numbers (seconds) where you always get the hours in 24 hour format.

Thanks again and have a good day,

Thanks a lot folks.
All been really helpful…

Much appreciated. The random timing script is pretty neat now. :slight_smile:

Im trying to anticipate any problems of this running over a number of weeks. Anyone think of anything?

Oh nearly forgot re: above posts
was actually “next file name” its part of “Audio Recorder” dictionary:

next file name  Unicode text  -- The file name for the next recording

Im with you all on using the time functions within applescript - I like Nigel’s sub routine - user-preference friendly idea… far nicer than relying on a shell script

Ill get it all done and post it up.

thanks again
w

Hi,

I must have an older version of Audio Recorder. So, if you’re going to run it on different version it might not work. Here’s the app properties for Audio Recorder version 1.3 (v1.3):

Class application: The Audio Recorder application.
Elements:
document by name, by numeric index, before/after another element, as a range of elements, satisfying a test
window by name, by numeric index, before/after another element, as a range of elements, satisfying a test, by ID
Properties:
application [r/o] – All of the properties of the superclass.
quality custom/radio/voice/CD/studio – The recording quality.
MP3 bit rate unsigned integer – The bit rate for MP3 recordings.
output format AIFF/MP3 – The output format for recordings.
output folder Unicode text – The output folder for recordings.
MP3 mode joint stereo/stereo/mono – The mode for MP3 recordings.
next filename Unicode text – The filename for the next recording.
current file path Unicode text [r/o] – The path of the most current recording.

gl,

ahhh ok I see where the next filename business comes from now. Thanks Kel. Ill just have to bundle Audio Recorder 1.4 with it.

Just so you know 1.4 has the same properties apart from:
duration (real)
volume (small real)
next file name (unicode)
duration as string (unicode)
output folder path (unicode) (NB: ‘path’)
next file name (unicode)
status (paused/recording/stopped)