FYI A persistent stopwatch, and other date/time manipulation examples.

This was written to show examples of how a stopwatch can persist over reboots, (to 1 second accuracy), and also shows how time from given dates can be determined.

I’m posting it because I found information on manipulating the date strings very difficult to find, and had to learn by trial and error, (and some help from fellow scripters) and so wrote this as a reference for myself (old age, the memory dims). :stuck_out_tongue:

I hope it’s useful.

Regards

Santa


-- Timer

-- Not bloody copyright
-- Just fooling around.
-- Some examples of how time strings can be manipulated,
-- cause I found examples hard to find.
-- by Santa



my Timer()
my displayInfo()

on Timer()
	copy (current date) - (time to GMT) to tempDate -- For universal time
	copy tempDate to KeepTheTime
	
	-- For an invisible file, put a full stop in front of the name ie ".Timer"
	set t to my ReadTheTime("Timer", KeepTheTime)
	display dialog "elapsed : " & my setTheDaysHoursMinutesSeconds(KeepTheTime - t) buttons {"OK", "See elapsed time", "Reset Timer"}
	set temp to button returned of the result
	if temp = "Reset Timer" then
		copy (current date) - (time to GMT) to tempDate -- For universal time
		my SaveTheTime("Timer", tempDate)
		my Timer()
	else
		if temp = "See elapsed time" then my Timer()
	end if
end Timer

on displayInfo()
	copy (current date) - (time to GMT) to tempDate -- For universal time
	copy tempDate to KeepTheTime
	set time of tempDate to 0
	set dayelapsedtime to KeepTheTime - tempDate
	set day of tempDate to 1
	set monthelapsedtime to KeepTheTime - tempDate
	set month of tempDate to 1
	set yearlyelapsedtime to KeepTheTime - tempDate
	
	display dialog "Universal time" & return & return & ¬
		"Since midnight, " & dayelapsedtime & " seconds have elapsed." & return & ¬
		my setTheDaysHoursMinutesSeconds(dayelapsedtime) & return & return & ¬
		"Since 12.00 am on the first of the month, " & monthelapsedtime & " seconds have elapsed." & return & ¬
		my setTheDaysHoursMinutesSeconds(monthelapsedtime) & return & return & ¬
		"Since 12.00 am January 1, " & yearlyelapsedtime & " seconds have elapsed." & return & ¬
		my setTheDaysHoursMinutesSeconds(yearlyelapsedtime) buttons {"OK", "Refresh information"}
	if button returned of the result = "Refresh information" then my displayInfo()
	
end displayInfo

on ReadTheTime(Filename, KeepTheTime)
	tell application "Finder"
		set TheFileName to (path to desktop folder as string) & Filename
		try
			set theSavedTime to (read file (TheFileName) as date)
			return theSavedTime
		on error
			my SaveTheTime(Filename, KeepTheTime)
			return KeepTheTime
		end try
	end tell
end ReadTheTime

on SaveTheTime(Filename, KeepTheTime)
	tell application "Finder"
		set TheFileName to (path to desktop folder as string) & Filename
	end tell
	set fRef to (open for access file TheFileName with write permission)
	set eof fRef to 0
	try
		write KeepTheTime to fRef
	end try
	close access fRef
end SaveTheTime

on setTheDaysHoursMinutesSeconds(theSeconds)
	
	set TheTotalDays to theSeconds div days
	set TheTotalHours to (theSeconds - (TheTotalDays * days)) div hours
	set thetotalminutes to (theSeconds - ((TheTotalDays * days) + (TheTotalHours * hours))) div minutes
	set theTotalSeconds to theSeconds - ((TheTotalDays * days) + (TheTotalHours * hours) + (thetotalminutes * minutes))
	set the AnswerString to ""
	if TheTotalDays > 0 then set the AnswerString to the AnswerString & TheTotalDays & " Days "
	if TheTotalHours > 0 then set the AnswerString to the AnswerString & TheTotalHours & " Hours "
	if thetotalminutes > 0 then set the AnswerString to the AnswerString & thetotalminutes & " Minutes "
	set the AnswerString to the AnswerString & theTotalSeconds & " Seconds."
	return the AnswerString
	
end setTheDaysHoursMinutesSeconds


Hi Santa,

nice script. :slight_smile:
One little note: for read/write operations the Finder isn’t needed at all.
And without the Finder you can write path to desktop instead of path to desktop folder

There’s a bug in intel imacs reading the time from a file (as of 10th Nov. 2007), so with a suggestion from Nigel Garvey I’ve re-written the script.



-- Timer

-- Not bloody copyright
-- Just fooling around.
-- Some examples of how time strings can be manipulated,
-- cause I found examples hard to find.
-- by Santa (10 Nov 2007)

my Timer()
my displayInfo()

on Timer()
	copy (current date) - (time to GMT) to tempDate
	-- For universal time
	copy tempDate to KeepTheTime
	
	-- For an invisible file, put a full stop in front of the name ie ".Timer"
	set t to my ReadTheTime("Timer", KeepTheTime)
	display dialog "elapsed : " & my setTheDaysHoursMinutesSeconds(KeepTheTime - t) buttons {"OK", "See elapsed time", "Reset Timer"}
	set temp to button returned of the result
	if temp = "Reset Timer" then
		copy (current date) - (time to GMT) to tempDate -- For universal time
		my SaveTheTime("Timer", tempDate)
		my Timer()
	else
		if temp = "See elapsed time" then my Timer()
	end if
end Timer

on displayInfo()
	copy (current date) - (time to GMT) to tempDate -- For universal time
	copy tempDate to KeepTheTime
	set time of tempDate to 0
	set dayelapsedtime to KeepTheTime - tempDate
	set day of tempDate to 1
	set monthelapsedtime to KeepTheTime - tempDate
	set month of tempDate to 1
	set yearlyelapsedtime to KeepTheTime - tempDate
	
	display dialog "Universal time" & return & return & ¬
		"Since midnight, " & dayelapsedtime & " seconds have elapsed." & return & my setTheDaysHoursMinutesSeconds(dayelapsedtime) & return & return & ¬
		"Since 12.00 am on the first of the month, " & monthelapsedtime & " seconds have elapsed." & return & my setTheDaysHoursMinutesSeconds(monthelapsedtime) & return & return & ¬
		"Since 12.00 am January 1, " & yearlyelapsedtime & " seconds have elapsed." & return & my setTheDaysHoursMinutesSeconds(yearlyelapsedtime) buttons {"OK", "Refresh information"}
	if button returned of the result = "Refresh information" then my displayInfo()
	
end displayInfo

on ReadTheTime(Filename, KeepTheTime)
	tell application "Finder"
		set TheFileName to (path to desktop folder as string) & Filename
		try
			set theSavedTime to (read file TheFileName as «class isot») as date
			return theSavedTime
		on error
			my SaveTheTime(Filename, KeepTheTime)
			return KeepTheTime
		end try
	end tell
end ReadTheTime

on SaveTheTime(Filename, KeepTheTime)
	tell application "Finder"
		set TheFileName to (path to desktop folder as string) & Filename
	end tell
	set fRef to (open for access file TheFileName with write permission)
	set eof fRef to 0
	try
		set KeepTheTime to KeepTheTime as «class isot»
		write KeepTheTime to fRef
	end try
	close access fRef
end SaveTheTime

on setTheDaysHoursMinutesSeconds(theSeconds)
	set TheTotalDays to theSeconds div days
	set TheTotalHours to (theSeconds - (TheTotalDays * days)) div hours
	set thetotalminutes to (theSeconds - ((TheTotalDays * days) + (TheTotalHours * hours))) div minutes
	set theTotalSeconds to theSeconds - ((TheTotalDays * days) + (TheTotalHours * hours) + (thetotalminutes * minutes))
	set the AnswerString to ""
	if TheTotalDays > 0 then set the AnswerString to the AnswerString & TheTotalDays & " Days "
	if TheTotalHours > 0 then set the AnswerString to the AnswerString & TheTotalHours & " Hours "
	if thetotalminutes > 0 then set the AnswerString to the AnswerString & thetotalminutes & " Minutes "
	set the AnswerString to the AnswerString & theTotalSeconds & " Seconds."
	return the AnswerString
end setTheDaysHoursMinutesSeconds


Model: intel Core 2 Duo iMac
AppleScript: 2.1.1
Browser: Safari 3.0.4
Operating System: Mac OS X (10.5)

Hi Santa,

two notes:

¢ in Leopard the text classes string, Unicode text and text are unified,
so it’s recommended to use only text in the future

¢ as mentioned in another thread, the Finder tell blocks in the read and save handlers are totally useless


.
on ReadTheTime(Filename, KeepTheTime)
	set TheFileName to (path to desktop folder as text) & Filename
	try
		set theSavedTime to (read file TheFileName as «class isot») as date
		return theSavedTime
	on error
		SaveTheTime(Filename, KeepTheTime)
		return KeepTheTime
	end try
	
end ReadTheTime

on SaveTheTime(Filename, KeepTheTime)
	set TheFileName to (path to desktop folder as text) & Filename
	set fRef to (open for access file TheFileName with write permission)
	set eof fRef to 0
	try
		set KeepTheTime to KeepTheTime as «class isot»
		write KeepTheTime to fRef
	end try
	close access fRef
end SaveTheTime
.

Thanks Stefan. I appreciate your telling me about the ‘text’ format.

I had noted that the finder tell blocks were redundant, but didn’t bother removing them in this script. Just slack I guess. :slight_smile:

It was more important to find a way of getting the time routine to work both in Tiger and Leopard. My main script that I’m having problems with has to work under both until the very second the script users switch incoming eMail from a Tiger G5 to a Leopard Intel iMac. I don’t want to maintain two script versions.

Regards

Santa

Model: intel Core 2 Duo iMac
AppleScript: 2.1.1
Browser: Safari 3.0.4
Operating System: Mac OS X (10.5)