Age Detector (volumedetect)

Written by Kitsune
// Get Days Old
// Original b yTravis Lambert -- 10-19-2005 (504 days old) :)  
// Re-Written by Hank Ramos Aug/8/2006
// Some functions by Christopher Omega 10/21/05
 
//Global Variables
list lNames;
 
//User Functions
integer min(integer a, integer b)
{
 if (a > b)
 return b;
 return a;
}
 
integer isLeapYear(integer year)
{
 return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
 
integer daysInMonth(integer month, integer year)
{
 if (month < 9) {
 if (month != 2) {
 // Before September, odd numbered months
 // are 31 days long.
 if (month % 2 != 0) {
 return 31;
 } else {
 return 30;
 }
 } else {
 // February is the odd man out.
 if (isLeapYear(year)) {
 return 29;
 } else {
 return 28;
 }
 }
 } else {
 // After August, odd numbered months
 // are 30 days long.
 if (month % 2 != 0) {
 return 30;
 } else {
 return 31;
 }
 }
}
 
float timestampDiff(string t1, string t2)
{
 if (t1 == t2)
 return 0;
 
 float diff = 0;
 integer year1 = (integer) llGetSubString(t1, 0, 3);
 integer year2 = (integer) llGetSubString(t2, 0, 3);
 integer i;
 if (year1 != year2) {
 integer minYear = min(year1, year2);
 integer maxYear = year1;
 if (minYear == year1)
 maxYear = year2;
 float secsBetween;
 secsBetween += 31536000 * (maxYear - minYear);
 for (i = minYear; i < maxYear; ++i) {
 if (isLeapYear(i))
 secsBetween += 86400; // Add extra day.
 }
 if (year2 == maxYear)
 secsBetween *= -1;
 diff += secsBetween;
 }
 
 integer month1 = (integer) llGetSubString(t1, 5, 6);
 integer month2 = (integer) llGetSubString(t2, 5, 6);
 if (month1 != month2) {
 integer month1Secs;
 for (i = 1; i < month1; ++i) {
 // 1 day = 24 hrs * 60 mins * 60 secs
 month1Secs += daysInMonth(i, year1);
 }
 month1Secs *= 86400; // Convert days into secs.
 integer month2Secs;
 for (i = 1; i < month2; ++i) {
 month2Secs += daysInMonth(i, year2);
 }
 month2Secs *= 86400;
 diff += month1Secs - month2Secs;
 }
 // Whew! Now everything past this point should be clear cut
 // conversion directly into seconds.
 integer days1 = (integer) llGetSubString(t1, 8, 9);
 integer days2 = (integer) llGetSubString(t2, 8, 9);
 diff += (days1 - days2) * 86400;
 integer hours1 = (integer) llGetSubString(t1, 11, 12);
 integer hours2 = (integer) llGetSubString(t2, 11, 12);
 diff += (hours1 - hours2) * 3600; //1 hr = 60 mins * 60 secs.
 integer minutes1 = (integer) llGetSubString(t1, 14, 15);
 integer minutes2 = (integer) llGetSubString(t2, 14, 15);
 diff += (minutes1 - minutes2) * 60;
 float secs1 = (float) llGetSubString(t1, 17, -2); // Skip last char.
 float secs2 = (float) llGetSubString(t2, 17, -2);
 diff += secs1 - secs2;
 return diff;
}
 
default
{
 state_entry()
 {
 llSetText(llGetObjectName(), <1,1,1>, 1);
 llVolumeDetect(TRUE);
 }
 
 collision_start(integer num_detected)
 //touch_start(integer num_detected)
 {
 integer x;
 
 //Loop through all the clicks
 for (x = 0; x < num_detected; x++)
 {
 lNames += llRequestAgentData(llDetectedKey(x), DATA_BORN);
 lNames += llDetectedName(x);
 }
 }
 dataserver(key kQueryid, string sData)
 {
 integer x;
 string  sName;
 integer iAge;
 
 //Loop through names in list
 for (x = 0; x < llGetListLength(lNames); x += 2)
 {
 if (kQueryid == llList2Key(lNames, x))
 {
 //Found our request
 sName = llList2Key(lNames, x + 1);
 lNames = llDeleteSubList(lNames, x, x + 1);
 iAge  = llRound(timestampDiff(llGetDate(), sData)/86400);
 if (iAge == 1)
 {
 llSay(0,sName + " is " + (string)iAge + " Day Old!");
 }
 else
 {
 llSay(0,sName + " is " + (string)iAge + " Days Old!");
 }
 }
 }
 }
}