Process items in a list and add to counter.

Hi Everybodies

I have been going round in circles and need the guidance of the geniuses out there.

I have a list:{{17362, 2, 3, “2015-06-15 06:17:19”, 40, 33, 1}, {17362, 2, 3, “2015-06-15 06:55:41”, 46, 26, 1}, {17362, 2, 2, “2015-06-15 06:58:21”, 36, 20, 1}}

What i am trying to achieve is to process the list but i need to process the records and get the value of item 7 of the record and also the next record if it is not more than 15 minutes older than the first record. If it is, then i need to store record one’s results set my new start time to item 2’s date and then process record 2 store the value of item 7 then process the next record and see if that is within 15 mins of record 2, if so add its value to the result.

the best method i have found with the dates is to turn them into epoch dates and compare against these.
EG "2015-06-15 06:17:19 in epoch is 1434346339, so by running set expiry to (epoch + 900) give me my 15 minus i am looking into.
Where i am seeming to get stuck is achieving a result like the example below in a text file:
Time Count
6:17 - 6:32 1
6:55 - 7:10 2

Any help is greatly appreciated, also any clarification i can help with, please let me know.

Many Thanks
Chris

Hi,

probably the most effective way to convert two date strings to date objects and calculate the difference is AppleScriptObjC


use framework "Foundation"

timeInterval since "2015-06-15 06:17:19" thru "2015-06-15 06:55:41" for "YYYY-MM-dd HH:mm:ss"

-- returns the time difference in seconds or missing value in case of a malformed string
on timeInterval since dateStringA thru dateStringB for dateFormat
	set dateFormatter to current application's NSDateFormatter's alloc()'s init()
	dateFormatter's setDateFormat:dateFormat
	set dateA to dateFormatter's dateFromString:dateStringA
	set dateB to dateFormatter's dateFromString:dateStringB
	if dateA is not missing value and dateB is not missing value then
		return (dateB's timeIntervalSinceDate:dateA) as integer
	end if
	return missing value
end timeInterval

Hi Stefan

Appreciate the info, but i find using unix timestamp works very well.

I have found that turning the date back into unix timestamp gives me a unique item to compare against.

What i need to do is for example:

set x to {{17362, 2, 3, “2015-06-15 06:17:19”, 40, 33, 1}, {17362, 2, 3, “2015-06-15 06:55:41”, 46, 26, 1}, {17362, 2, 2, “2015-06-15 06:58:21”, 36, 20, 1}}

Then i convert the time to a unix timestamp.
set the_time to do shell script "“date -j -f ‘%Y-%m-%d %H:%M:%S’ '” & x & “’ +%s”

This then gives me a epoch timestamp i can use to compare.

i will use this time to search for items that are between this value and a (value+900 this would equal 15mins)
Anything matching in that time slot would then have item 7 of the record would be added to a variable in a counting method.

Once the times did not match anymore i would write these out to a file and then reset the counting variable, get the timestamp from the next record item and start the process over again.

Hope this makes it clearer

Chris

Dates in AppleScript (typeLongDate; 64-bit signed integer) is number of seconds since “Friday, 1 January 1904 00:00:00”. So they can be easily added and subtracted from each other as well, like epoch time.

set theList to {{17362, 2, 3, "2015-06-15 06:17:19", 40, 33, 1}, {17362, 2, 3, "2015-06-15 06:55:41", 46, 26, 1}, {17362, 2, 2, "2015-06-15 06:58:21", 36, 20, 1}}
set startTime to 1
set output to {{"Date		Time				Count"}}

repeat with x from 1 to count theList
	set item 4 of item x of theList to isoTimeStringToDate(item 4 of item x of theList)
	if (item 4 of item x of theList) - (item 4 of item startTime of theList) > 900 then
		set end of output to createLine(item 4 of item startTime of theList, x - startTime)
		set startTime to x
	end if
end repeat

set end of output to createLine(item 4 of item startTime of theList, x - startTime + 1)

tell AppleScript
	set oldTIDs to text item delimiters
	set text item delimiters to linefeed
	set output to output as string
	set text item delimiters to oldTIDs
end tell

return output

on createLine(theDate, theCount)
	set startIsot to theDate as «class isot» as string
	set endIsot to (theDate) + 900 as «class isot» as string
	set theLine to text 1 thru 10 of startIsot
	set theLine to theLine & tab
	set theLine to theLine & text 12 thru -1 of startIsot & " - " & text 12 thru -1 of endIsot
	set theLine to theLine & tab & theCount
	return theLine
end createLine

on isoTimeStringToDate(isot)
	if character 11 of isot is space then
		set chars to characters of isot
		set item 11 of chars to "T"
		set isot to chars as string
	end if
	set hex to stringToHex(isot)
	run script ("return «data isot" & hex & "» as date")
end isoTimeStringToDate

on stringToHex(str)
	-- NOTE: this handler only works for characters in range 0 - 255
	-- which is fine for isotime strings
	set hexChars to "0123456789ABCDEF"
	set hexStr to ""
	repeat with IDs in id of str
		set hexStr to hexStr & character ((IDs div 16) + 1) of hexChars
		set hexStr to hexStr & character ((IDs mod 16) + 1) of hexChars
	end repeat
	return hexStr
end stringToHex

Hello.

An alternative to the unix epoch is to use the time property of the date object, this gives the time in seconds since midnight.

If the timings go around the clock, then you must add 84600 seconds or so, for each day the current date differs from the start date. ( day of (current date) as integer).

(sigh), day is always an integer

date (noun), pl dates: A date-time value. . day get integer The day of the month of a date.
:wink:

Sorry about that, I mixed it with weekday, and at least it doesn’t break the code. :slight_smile:

Those properties can be used, together with mod and div, and the handlers DJ Bazzie Wazzie provided above, to perform the time arithmetic from within AppleScript.

As DJ suggests, you don’t really need to do that, but let’s assume you did. Converting two dates to unix timestamps and subtracting them on my Mac takes about 30 times as long as the handler Stefan posted. Using “do shell script” has a lot of overhead – don’t mistake lines of code with time taken to run.

If you’re not dealing with a lot of data, it’s academic. But if you were, you might want to adjust your definition of “works very well”.

Thanks guys and point taken shane. Yes cycle counts are important as i will be processing lots of data, so i will take your examples and build it again.

Thank you DJ Bazzie Wazzie, your code works a charm. And means i can keep what hair is left on my head.
I can see the difference in the run time immediately, a vast improvement.

Thanks guys.