Applescript set string to date and add 30 minutes

I am trying to fill in 2 time boxes on a website in Safari using Applescript based on buttons selected by the user.


My current Applescript is:


set dialog to display dialog "When did your first case start?" buttons {"07:30, "08:00, "08:30"}

set start to button returned of the result


inputByName("Time1", 0, start)


set test to "07:30" --assuming the user selected "07:30" in the dialog box

date test --not sure how to assign 07:30 as a time


set finish to test + (30 * minutes)


inputByName("Time2", 0, finish)


The error coming back is "Invalid date and time date 07:30 of <<script>>." number -30720

Any help would be greatly appreciated!


Thank you


s

MacBook Pro with Retina display, OS X El Capitan (10.11.4)

Posted on May 7, 2016 7:36 PM

Reply
11 replies

May 8, 2016 3:36 AM in response to red_menace

Thank you red_menace! That does work and allows me to manipulate the user's input as a time. I only have one more question on this topic. Right now the Applescript is returning the result "8:00:00 AM" assuming the user selected "07:30"


if start is equal to "07:30" then

tell (current date)

set its time to (7 * hours) + (30 * minutes)

set someDate to it

set finish to someDate + (30 * minutes)

end tell

return time string of finish

end if

The format of finish needs to be 00:00 - 23:59 so I would need to convert "08:00:00 AM" to "08:00". Is there an easy way to do this?

Thank you.

May 8, 2016 4:27 AM in response to shockedlattice

Hello


You might try something like the following script.



set s to 7 * hours + 30 * minutes return time_in_hhmm(s + 30 * minutes) -- "08:00" on time_in_hhmm(s) (* integer s : seconds from 00:00:00 return string : time in hh:mm notation *) set t to current date set t's time to s (t as «class isot» as string)'s text 12 thru 16 end time_in_hhmm




Good luck,

H

May 8, 2016 6:56 AM in response to shockedlattice

The time property of an AppleScript date object is the number of seconds since midnight - another way to convert the time to text is to extract the hours and minutes from the seconds (the following script uses a general purpose handler that you can reuse):


set theTimes to {"07:30", "08:00", "08:30"} -- some time choices

set choice to (choose from list theTimes with prompt "When did your first case start?" without multiple selections allowed and empty selection allowed) as text
if choice is "false" then error number -128 -- quit

set {HH, MM} to {choice's text 1 thru 2, choice's text 4 thru 5} -- break out time components

tell (current date) -- create date object from current date/time
  set its time to (HH * hours) + (MM * minutes) -- set time
  set its time to ((its time) + 30 * minutes) -- add 30 minutes
  set someDate to it
end tell

return timeToText(someDate's time) -- format time to 24 hour and return result


on timeToText(theTime) -- format theTime in seconds to HH:MM:SS
  if class of theTime is integer then tell ¬
    "00000" & (10000 * (theTime mod days div hours) + ¬
    100 * (theTime mod hours div minutes) + ¬
    (theTime mod minutes)) as text ¬
    to set theTime to (text -6 thru -5) & ":" & (text -4 thru -3) -- & ":" & (text -2 thru -1)
  return theTime
end timeToText

May 8, 2016 2:24 PM in response to red_menace

OK Script Editor is returning exactly the format I need. I just can't get 'theTime' out of the subroutine in order to put it into the safari text box.

Time1 will be what the user originally selects from list "theTimes"

Time2 will add 30 minutes to that selection in format "08:00". Script editor ends with result "08:00" but I can not send that to Safari.

I apologize, but I am very new to Applescript and still learning as I go.

If this is helpful here is the source code from the website:

</font></b><font size="2"><b>Anesthesia Start

(AS):</b></font></td>

<td width="50%" bgcolor="#99CCFF"><input type="text" name="Time1" size="7" value="" ONKEYPRESS="return handleEnter(this, event)" onBlur="parseelement(this);IsValidTime(this);"><input type="button" name="b1" size="20" value="Time Stamp" onclick="javascript:document.FrontPage_Form1.Time1.value=time;"><input type="button" name="b9" size="20" value="Erase" onclick="javascript:document.FrontPage_Form1.Time1.value='';"></td>

</tr>

<tr>

<td width="50%" align="right" bgcolor="#99CCFF"><font size="2"><b><img src='../../images/warn.gif'> <font><font size="2"><img border="0" src="../../images/required5.gif" width="9" height="9"></font>

</font>Anesthesia

Finish (AF):</b></font></td>

<td width="50%" bgcolor="#99CCFF"><input type="text" name="Time2" size="7" value="" ONKEYPRESS="return handleEnter(this, event)" onBlur="parseelement(this);IsValidTime(this);"><input type="button" name="b3" size="20" value="Time Stamp" onclick="javascript:document.FrontPage_Form1.Time2.value=time;"><input type="button" name="b11" size="20" value="Erase" onclick="javascript:document.FrontPage_Form1.Time2.value='';"></td>

</tr>

set theTimes to {"07:30", "08:00", "08:30"} -- some time choices


set choice to (choose from listtheTimeswith prompt "When did your first case start?" without multiple selections allowed and empty selection allowed) as text

if choice is "false" then error number -128 -- quit


set {HH, MM} to {choice's text 1 thru 2, choice's text 4 thru 5} -- break out time components


tell (current date) -- create date object from current date/time

set its time to (HH * hours) + (MM * minutes) -- set time

set its time to ((its time) + 30 * minutes) -- add 30 minutes

set someDate to it

end tell


set start to someDate


inputByName("Time1", 0, choice)


return timeToText(someDate'stime) -- format time to 24 hour and return result


on timeToText(theTime) -- format theTime in seconds to HH:MM:SS

if class of theTime is integer then tell ¬

"00000" & (10000 * (theTime mod days div hours) + ¬

100 * (theTime mod hours div minutes) + ¬

(theTime mod minutes)) as text ¬

to set theTime to (text -6 thru -5) & ":" & (text -4 thru -3) -- & ":" & (text -2 thru -1)

return theTime

end timeToText


tell application "Safari"

do JavaScript "document.getElementsByName('Time2')[0].theTime;" in document 1

end tell

Thank you!

May 8, 2016 3:24 PM in response to shockedlattice

My earlier examples just returned the time string - you would use your other statements instead of returning the formatted time, for example:


set theTime to timeToText(someDate's time) -- format time to 24 hour
inputByName("Time1", 0, choice)
tell application "Safari"
  do JavaScript "document.getElementsByName('Time2')[0].theTime;" in document 1
end tell


I'm not up on the nuances of javascript, but I'm not seeing what you are indexing into with the Time2 element or what theTime method is. Are you trying to get/set a value? And what is the inputByName hander?

May 9, 2016 3:40 PM in response to shockedlattice

You might try this.



set s to choose from list {"07:30", "08:00", "08:30"} if s = false then error number -128 -- user cancel set s to s's item 1 set {h, m} to {0 + (s's text 1 thru 2), 0 + (s's text 4 thru 5)} set t to time_in_hhmm(h * hours + (m + 30) * minutes) --return {s, t} setValueOfElementByName_index_value("Time1", 0, s) setValueOfElementByName_index_value("Time2", 0, t) on time_in_hhmm(s) (* integer s : seconds from 00:00:00 return string : time in hh:mm notation *) set t to current date set t's time to s (t as «class isot» as string)'s text 12 thru 16 end time_in_hhmm on setValueOfElementByName_index_value(n, i, v) (* string n : DOM element name integer i : index of the target element in collection string v : value to which the target element's value is set *) set js to "document.getElementsByName('" & n & "')[" & i & "].value = '" & v & "';" tell application "Safari" to do JavaScript js in window 1's current tab end setValueOfElementByName_index_value




Regards,

H

May 9, 2016 3:44 PM in response to shockedlattice

On the time part, using AppleScript's word simplifies the string manipulation a little, e.g.:


set c to choose from list {"07:30", "08:00", "08:30"}


tell c's item 1 to set s to (word 1) * hours + ((word 2) + 30) * minutes


set t to timeInHHMM(s)


to timeInHHMM(s)

set t to current date

set t's time to s

(t as «class isot» as string)'s text 12 thru 16

end timeInHHMM





SG

May 10, 2016 3:51 PM in response to SGIII

Well, I thought I had this figured out.

The script below works perfectly for entering "07:30" into "Time1" and "08:00" into "Time2". The script will save the info and reload the page to log another time. This time needs to now be "08:00" into "Time1" and "08:30" into "Time2" and then repeats again (based on the user's input into cases) so that the 3rd time will be "08:30" into "Time1" and "09:00" into "Time2" and so on.


I am able to get this to work if I keep defining variables and rewriting time_in_hhmm with variables s and t, then t and t2, then t2 and t3, etc with each run adding 30 min, but is there a better way to do this? I do not know what the user will enter for cases, and it could be as high as 20. Hopefully that made sense.


Here is the script I have so far.

on time_in_hhmm(s)


(*

integer s : seconds from 00:00:00

return string : time in hh:mm notation

*)

set t to current date

set t's time to s

(t as «class isot» as string)'s text 12 thru 16

end time_in_hhmm


on setValueOfElementByName_index_value(n, i, v)


(*

string n : DOM element name

integer i : index of the target element in collection

string v : value to which the target element's value is set

*)

set js to "document.getElementsByName('" & n & "')[" & i & "].value = '" & v & "';"

tell application "Safari" to do JavaScriptjsinwindow 1's current tab

end setValueOfElementByName_index_value


to inputByName(theName, num, theValue)

tell application "Safari"

do JavaScript "document.getElementsByName('" & theName & "')[" & num & "].value='" & theValue & "';" in document 1

end tell

end inputByName


to clickName(theName, elementnum)

tell application "Safari"

do JavaScript "document.getElementsByName('" & theName & "')[" & elementnum & "].click();" in document 1

end tell

end clickName


set dialog to display dialog "How many cases do you want to enter?" default answer ""

set cases to text returned of the result

set originalcase to cases


set s to choose from list {"07:30", "08:00", "08:30"}

if s = false then error number -128 -- user cancel

set s to s's item 1

set {h, m} to {0 + (s's text 1 thru 2), 0 + (s's text 4 thru 5)}

set t to time_in_hhmm(h * hours + (m + 30) * minutes)

--return {s, t}


repeat until cases = 0


if cases < originalcase then


setValueOfElementByName_index_value("Time1", 0, s)


setValueOfElementByName_index_value("Time2", 0, t)

end if


set js to "

var ee = document.evaluate(

'//a[contains(., \"Save this case, then start a NEW case on the SAME DAY\")]',

document,

null,

XPathResult.FIRST_ORDERED_NODE_TYPE,

null

);

var e = ee.singleNodeValue;

var evt = document.createEvent('MouseEvent');

evt.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);

e.dispatchEvent(evt);

"

tell application "Safari"


activate


do JavaScriptjsinwindow 1's current tab

end tell


set cases to cases - 1


end repeat

May 11, 2016 3:40 PM in response to shockedlattice

So far what I've got is giving me the following:


On first run of the repeat Time1 correctly enters 07:30 and Time2 correctly enters 08:00

On second run of the repeat Time1 correctly enters 08:00 and Time2 correctly enters 08:30

On third run and any subsequent run Time1 is always 08:30 and Time2 is always 08:30.


What am I doing that is not keeping the loop running of adding 30 minutes after the second time through?


Here is the code I've got so far:


on time_in_hhmm(s)


(*

integer s : seconds from 00:00:00

return string : time in hh:mm notation

*)

set t to current date

set t's time to s

(t as «class isot» as string)'s text 12 thru 16

end time_in_hhmm


on time_in_hhmm2(t)


(*

integer t : seconds from 00:00:00

return string : time in hh:mm notation

*)

set t2 to current date

set t2's time to (t + (30 * minutes))

(t2 as «class isot» as string)'s text 12 thru 16

end time_in_hhmm2



on setValueOfElementByName_index_value(n, i, v)


(*

string n : DOM element name

integer i : index of the target element in collection

string v : value to which the target element's value is set

*)

set jstime to "document.getElementsByName('" & n & "')[" & i & "].value = '" & v & "';"

tell application "Safari" to do JavaScriptjstimeinwindow 1's current tab

end setValueOfElementByName_index_value


to inputByName(theName, num, theValue)

tell application "Safari"

do JavaScript "document.getElementsByName('" & theName & "')[" & num & "].value='" & theValue & "';" in document 1

end tell

end inputByName


to clickName(theName, elementnum)

tell application "Safari"

do JavaScript "document.getElementsByName('" & theName & "')[" & elementnum & "].click();" in document 1

end tell

end clickName


set dialog to display dialog "How many cases do you want to enter?" default answer ""

set cases to text returned of the result

set originalcase to cases


set s to choose from list {"07:30", "08:00", "08:30"}

if s = false then error number -128 -- user cancel

set s to s's item 1

set {h, m} to {0 + (s's text 1 thru 2), 0 + (s's text 4 thru 5)}

set t to time_in_hhmm(h * hours + (m + 30) * minutes)

--return {s, t}


setValueOfElementByName_index_value("Time1", 0, s)

setValueOfElementByName_index_value("Time2", 0, t)


repeat until cases = 0


if cases < originalcase then


setValueOfElementByName_index_value("Time1", 0, t)

set t2 to time_in_hhmm2(h * hours + (m + 30) * minutes)


setValueOfElementByName_index_value("Time2", 0, t2)

set t to t2

end if


set js to "

var ee = document.evaluate(

'//a[contains(., \"Save this case, then start a NEW case on the SAME DAY\")]',

document,

null,

XPathResult.FIRST_ORDERED_NODE_TYPE,

null

);

var e = ee.singleNodeValue;

var evt = document.createEvent('MouseEvent');

evt.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);

e.dispatchEvent(evt);

"

tell application "Safari"


activate


do JavaScriptjsinwindow 1's current tab

end tell


set cases to cases - 1


end repeat

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Applescript set string to date and add 30 minutes

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.