Hi, i’m trying to take 2 dates, and get an ‘average’ of the 2.
ie.
(date "Wednesday, August 2,2006"+date "Monday, July 31,2006")/2
But of course, the ‘/2’ doesn’t work and returns an error. I’ve searched the forums a bit, and read the ‘date/time arithmatic’ doc, but that doesn’t help me do what I want
BTW: This is a great place for newbie applescripters (like me, sorta)!
You need to describe what you think the answer should be? Do you want a day half way between the two given? Given D1 later than D2 (not checked or corrected), this will find the “average” defined as the date half-way between.
to findMidwayDate(date_1, date_2)
set halfWay to ((date_1 - date_2) / days) / 2
return date_2 + halfWay * days
end findMidwayDate
findMidwayDate(current date, date "Thursday, June 1, 2006 12:00:00 AM")
Edited for general form. Works for either order of the dates.
-- just building a date list
set n to 5
set cur_date to (current date)
set date_list to {cur_date}
set s to 0
repeat n times
set s to s + 30
set end of date_list to cur_date + s
end repeat
-- now, there are six dates sorted in date_list
-- you need to find earliest date
-- if date_list is not sorted, then find the lowest date and record it
-- duplicate dates don't matter
-- since the list is sorted, the first item is lowest date
set low_date to item 1 of date_list
set sec_count to 0
repeat with this_date in date_list
set s to this_date - low_date
set sec_count to sec_count + s
end repeat
set sec_average to sec_count div (count date_list)
set average_date to low_date + sec_average
The last result should be one minute and fifteen seconds from th time you run the script (i.e. [(sum of n from 0 to 5) * 30] div 6, where 0 is the seconds for the lowest date).
Edited: my explaination. I forgot how to represent sums :).
If you want to more accurate, you could use the ‘round’ command.
-- just building a date list
set n to 5
set cur_date to (current date)
set date_list to {cur_date}
set s to 0
repeat n times
set s to s + 30
set end of date_list to cur_date + s
end repeat
-- now, there are six dates sorted in date_list
-- you need to find earliest date
-- if date_list is not sorted, then find the lowest date and record it
-- duplicate dates don't matter
-- since the list is sorted, the first item is lowest date
set low_date to item 1 of date_list
set sec_count to 0
repeat with this_date in date_list
set s to this_date - low_date
set sec_count to sec_count + s
end repeat
set sec_average to round (sec_count / (count date_list))
set average_date to low_date + sec_average
Turns out this gives the answer to the nearest second without any units imposed:
to findMidway(date_1, date_2)
set halfWay to (date_1 - date_2) / 2
return date_2 + halfWay
end findMidway
findMidway(date "Tuesday, August 1, 2006 12:44:18 PM", date "Thursday, June 1, 2006 2:34:14 AM")
--> date "Saturday, July 1, 2006 7:39:16 PM"
findMidway(date "Tuesday, August 1, 2006 12:44:18 PM", date "Tuesday, August 1, 2006 6:34:14 PM")
--> date "Tuesday, August 1, 2006 3:39:16 PM"
So here’s a near final script to get the average date from a list of dates.
-- just making a list of random dates
set base_date to (current date)
set date_list to {base_date}
repeat 5 times
set r to random number from 0 to days
set this_date to base_date + r
set end of date_list to this_date
end repeat
-- find the lowest date
-- you can repeat through the list or set an epoch date
set lowest_date to item 1 of date_list
repeat with this_date in date_list
if (contents of this_date) < lowest_date then set lowest_date to this_date
end repeat
-- map dates to seconds, and get total
set seconds_total to 0
repeat with this_date in date_list
set seconds_diff to this_date - lowest_date
set seconds_total to seconds_total + seconds_diff
end repeat
-- get average seconds
set seconds_average to (seconds_total) / (count date_list)
set average_date to base_date + seconds_average
Note that if you’re using unix dates, you could use the epoch date as a base date instead of searching through the list. Also, if you have a lot of dates, then you could speed this up considreably.
on average_date from l
set {b, s} to {l's beginning, 0}
repeat with i in l's rest
set s to i - b + s
end repeat
b + s div (count l)
end average_date
average_date from {date "Tuesday, August 1, 2006 12:44:18", date "Thursday, June 1, 2006 02:34:14"}
--> date "Saturday, July 1, 2006 19:39:16"
Neat, Kai. Your version will do a long list of dates like: {date “Tuesday, August 1, 2006 12:44:18 PM”, date “Thursday, June 1, 2006 2:34:14 AM”, date “Tuesday, August 15, 2006 7:44:12 PM”, date “Friday, June 23, 2006 11:32:23 AM”, current date}