Re: Age Anniversary Calculations
Dear Phil, Thank you *so much* for this link: On 24/05/2012, at 10:51 AM, Phil Davis wrote: Another good resource for date time calcs is Sarah Reichelt's DateTime.rev library, which is pure LC: http://www.troz.net/rev/index.irev?category=Library#stacks That is some very useful stuff, indeed - loads of useful functions! I see that this library overcomes the '1970' problem by internally converting all dates to a Julian Date format. Clever, and makes me feel very glad that I don't have to re-invent the wheel! Once again, many many thanks for the tip. -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
You are completely welcome! Sarah is one of the sharper knives in the drawer (and community-minded). I'm not sure if she still reads the list but she is missed. Phil On 5/24/12 5:09 PM, Igor de Oliveira Couto wrote: Dear Phil, Thank you *so much* for this link: On 24/05/2012, at 10:51 AM, Phil Davis wrote: Another good resource for date time calcs is Sarah Reichelt's DateTime.rev library, which is pure LC: http://www.troz.net/rev/index.irev?category=Library#stacks That is some very useful stuff, indeed - loads of useful functions! I see that this library overcomes the '1970' problem by internally converting all dates to a Julian Date format. Clever, and makes me feel very glad that I don't have to re-invent the wheel! Once again, many many thanks for the tip. -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode -- Phil Davis ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Sorry about that Igor, not sure why it didn't make it. Anyway, here it is again. AGE CALCULATION (using 1945-07-06 as the birth date): SELECT (strftime('%Y','now') - strftime('%Y','1945-07-06')) - (strftime('%m'-%d','now') strftime('%m-%d','1945-07-06')); CLOSE TO (Using 2012-05-30 as the anniversary date, 2012-05-23 as the target date, and 259200 as the4 seconds (=3 days): SELECT (date('2012-05-23','+ 259200 seconds') = date('2012-05-30')) Note that this returns 1 or zero rather than true or false. Also, you can use days, hours, minutes, months as the interval rather than seconds, e.g.: SELECT (date('2012-05-23','+ 3 days') = date('2012-05-30')) You can find complete description of all the sqlite date expressions at http://www.sqlite.org/lang_datefunc.html Hope that helps. Pete lcSQL Software http://www.lcsql.com On Tue, May 22, 2012 at 10:56 PM, Igor de Oliveira Couto i...@superstudent.net wrote: On 23/05/2012, at 3:50 PM, Peter Haworth wrote: I don't know the answer to your question about dates prior to 1970 on Windows machines, but I do know that problem doesn't exist with the sqlite solution I posted. [...] Peter, I went through my mail again to make sure, and I can't seem to find this post from you. Would you mind sending it again? - I would really like to see your suggestion! Many thanks in advance, -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Peter, thank you very much for the sqlite-based answers: On 24/05/2012, at 2:17 AM, Peter Haworth wrote: Sorry about that Igor, not sure why it didn't make it. Anyway, here it is again. [...] Indeed, it may be easier to let an external lib handle the date calculations, considering that it seems that there are many caveats if trying to use LiveCode functions alone. It is a bit of a pity - I really would have liked to have seen a 'simple' LiveCode-only solution, like most languages have... Many thanks for everyone's input and suggestions. -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Another good resource for date time calcs is Sarah Reichelt's DateTime.rev library, which is pure LC: http://www.troz.net/rev/index.irev?category=Library#stacks Phil Davis On 5/23/12 5:42 PM, Igor de Oliveira Couto wrote: Peter, thank you very much for the sqlite-based answers: On 24/05/2012, at 2:17 AM, Peter Haworth wrote: Sorry about that Igor, not sure why it didn't make it. Anyway, here it is again. [...] Indeed, it may be easier to let an external lib handle the date calculations, considering that it seems that there are many caveats if trying to use LiveCode functions alone. It is a bit of a pity - I really would have liked to have seen a 'simple' LiveCode-only solution, like most languages have... Many thanks for everyone's input and suggestions. -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode -- Phil Davis ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Many thanks for all the suggestions - and I did learn a couple of new tricks from your code, too! I had not realised that there could be an issue with pre-1970 dates in Windows, and also did not know that we had to watch out for the 'centuryCutoff' property. Very, very useful to know. Peter's code seems to be the most succinct - and flexible - for calculating the age: On 22/05/2012, at 6:01 AM, Peter M. Brigham, MD wrote: function doAge tDate,asOf -- returns the age given birthdate = tDate -- as of the date asOf (if empty, assumes today) if tDate = empty then return empty if asOf = empty then put the date into asOf end if set the itemdelimiter to / put item -1 of the short date into nowYr set the centurycutoff to nowYr+1 set the itemdelimiter to comma convert tDate to dateItems convert asOf to dateitems put item 1 of asOf - item 1 of tDate - 1 into tAge put item 1 of asOf into item 1 of tDate convert tDate to seconds convert asOf to seconds if tDate = asOf then add 1 to tAge return tAge end doAge This, however, does not seem to handle the 'before 1970' problem in Windows - ie., 'convert tDate to dateItems' here should fail in Windows, if tDate is before 1970. Is that correct, or am I missing something obvious? -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
HI Igor, I don't know the answer to your question about dates prior to 1970 on Windows machines, but I do know that problem doesn't exist with the sqlite solution I posted. You don't even have to have an sqlite database available to you, just call revOpenDatabase with :memory: as the file path. That creates an empty database in memory (no disk file) which disappears when your application closes, but will accept the SELECT statements. I use sqlite like this for any date calculations and it's never let me down yet, much more precise and succinct than any LC solution. Pete lcSQL Software http://www.lcsql.com On Tue, May 22, 2012 at 10:00 PM, Igor de Oliveira Couto i...@superstudent.net wrote: Many thanks for all the suggestions - and I did learn a couple of new tricks from your code, too! I had not realised that there could be an issue with pre-1970 dates in Windows, and also did not know that we had to watch out for the 'centuryCutoff' property. Very, very useful to know. Peter's code seems to be the most succinct - and flexible - for calculating the age: On 22/05/2012, at 6:01 AM, Peter M. Brigham, MD wrote: function doAge tDate,asOf -- returns the age given birthdate = tDate -- as of the date asOf (if empty, assumes today) if tDate = empty then return empty if asOf = empty then put the date into asOf end if set the itemdelimiter to / put item -1 of the short date into nowYr set the centurycutoff to nowYr+1 set the itemdelimiter to comma convert tDate to dateItems convert asOf to dateitems put item 1 of asOf - item 1 of tDate - 1 into tAge put item 1 of asOf into item 1 of tDate convert tDate to seconds convert asOf to seconds if tDate = asOf then add 1 to tAge return tAge end doAge This, however, does not seem to handle the 'before 1970' problem in Windows - ie., 'convert tDate to dateItems' here should fail in Windows, if tDate is before 1970. Is that correct, or am I missing something obvious? -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
On 23/05/2012, at 3:50 PM, Peter Haworth wrote: I don't know the answer to your question about dates prior to 1970 on Windows machines, but I do know that problem doesn't exist with the sqlite solution I posted. [...] Peter, I went through my mail again to make sure, and I can't seem to find this post from you. Would you mind sending it again? - I would really like to see your suggestion! Many thanks in advance, -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
On 21/05/2012 08:02, Igor de Oliveira Couto wrote: What is the 'best' way to perform these 2 calculations with LiveCode? 'convert' just rocks. Here's a couple of throwaways to show you how I'd approach it. They probably aren't exactly what you need, but you'll get the idea. 1) Calculate a person's age, given a birthdate: This one is a pain, as I ran it on Windows, and birthdays before 1970 weren't natively handled. I think this does the trick. --- on mouseUp -- put the birthday into tBd, -- on windows, can't do before 1970! put May 21 1965 into tBd -- handle 1970 (is this just on windows?) set the itemdel to put item 3 of tBd into tBYear if tBYear 12 then add 2000 to tBYear else if tBYear 100 then add 1900 to tBYear end if put 0 into tBYearOffset if tBYear 1970 then put 1970 - tBYear into tBYearOffset put 1970 into item 3 of tBd end if -- back to out regularly scheduled code set the itemdel to , convert tBd to dateItems if the result is not empty then put Got an error:the result else put the long time into tNow convert tNow to dateItems subtract tBYearOffset from item 1 of tBd put item 1 of tNow - item 1 of tBd into tBirthdays answer You've had tBirthdays birthdays. end if end mouseUp --- 2) Calculate whether an *anniversary* falls within a time frame - ie., within a week, within 2 weeks, within a month of today: Something like this perhaps (written as in a button script)...watch out for wrapping: --- on mouseUp -- get now as 2012,5,21,9,12,20,2 - today's date/time/day number put the long time into tNow convert tNow to dateItems -- find out this year's anniversary, replace '7' and '8' as needed put tNow into tAnniv put 6 into item 2 of tAnniv put 8 into item 3 of tAnniv -- find out distance between... convert tNow to seconds convert tAnniv to seconds put tAnniv - tNow into tDiff if tDiff 0 then answer Already passed! else convert tDiff to dateItems answer it's in item 2 of tDiff months, item 3 of tDiff \ days, item 4 of tDiff hours. end if -- difference is shown as - 1970,2,18,0,0,0,4 -- Ignore the year, as we purposely end mouseUp --- Hope this helps. -Ken ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Bonjour Igor, Le 21 mai 2012 à 09:02, Igor de Oliveira Couto a écrit : Dear LC Folks, What is the 'best' way to perform these 2 calculations with LiveCode? 1) Calculate a person's age, given a birthdate: I had problems with scripts mainly based on convert to seconds and dateItems also, on windows, as Ken points it out, with birthday before 1970. Eventually I wrote the following script (probably not the best ;-) but which works for months now, on Mac and Windows as well. It minimizes the recourse to convert to seconds. Notice that ages under one year, are returned in months. As it is written, it requires 2 fields : a fld fldBirthDay and a fld fldAge HTH Best regards from Grenoble André local tBirthDate,tAge,tToday,tLivedSecs,t1stYearSecs,t1YearSecs,\ tBirthDateSecs,tToDaySecs,tAddedMonths,date1,date2,tYearsNbr,tempo, on mouseUp lock screen -- ENGLISH DATE put fld fldBirthDay into tBirthDate put the short date into tToday set the itemDel to slash ==IN CASE OF YY FOR YEAR FORMAT == if the number of chars of item 3 of tBirthDate is 2 then if item 3 of tBirthDate item 3 of tToday then put 19 before item 3 of tBirthDate put 19 before item 3 of fld fldBirthDay else put 20 item 3 of tBirthDate into date1 put 19 item 3 of tBirthDate into date2 answer Sorry! can't decide ;-) with date1 or date2 put it into item 3 of fld fldBirthDay put it into item 3 of tBirthDate end if end if if the number of chars of item 3 of tToday is 2 then put 20 before item 3 of tToday -- put 20 before item 3 of fld fldJourdhui end if PRECAUTION FOR ENDS OF MONTH if item 1 of tToday is 2 and item 2 of tToday is among the items of 29/30/31 then put 28 into item 2 of tToday end if if item 1 of tToday is among the items of 4/6/9/11 then if item 2 of tToday is 31 then put 30 into item 2 of tToday end if put item 3 of tToday - item 3 of tBirthDate into tYearsNbr - PUTTING IN MONTHS BEFORE 1 YEAR -- USING CONVERT TO SECONDS put tBirthDate into tBirthDateSecs put tToday into tToDaySecs convert tBirthDateSecs to seconds convert tToDaySecs to seconds put tBirthDate into t1stYearSecs add 1 to item 3 of t1stYearSecs convert t1stYearSecs to seconds put t1stYearSecs - tBirthDateSecs into t1YearSecs put tToDaySecs - tBirthDateSecs into tLivedSecs put t1stYearSecs - tBirthDateSecs into t1YearSecs if tLivedSecs = t1YearSecs then monthsCount else yearsCount end if end mouseUp on monthsCount set the itemDel to slash put item 3 of tToday - item 3 of tBirthDate into tYearsNbr == if tYearsNbr = 0 then if tYearsNbr = 0 then put 0 into tAddedMonths if tYearsNbr = 1 then put 12 into tAddedMonths switch case item 1 of tToday item 1 of tBirthDate if item 2 of tToday item 2 of tBirthDate then put tAddedMonths + item 1 of tToday - item 1 of tBirthDate - 1 month into tAge else put tAddedMonths + item 1 of tToday - item 1 of tbirthDate month into tAge end if break case item 1 of tToday = item 1 of tBirthDate if item 2 of tToday item 2 of tBirthDate then put tAddedMonths - 1 month into tAge end if if item 2 of tToday = item 2 of tBirthDate then put tAddedMonths month into tAge end if break case item 1 of tToday item 1 of tBirthDate if item 2 of tToday item 2 of tBirthDate then put tAddedMonths + item 1 of tToday - item 1 of tBirthDate -1 month into tAge end if if item 2 of tToday = item 2 of tBirthDate then put tAddedMonths + item 1 of tToday - item 1 of tBirthDate month into tAge end if end switch end if - if word 1 of tAge 1 then put months into word 2 of tAge if char 1 of tAge is - then put not born yet into tAge if tAge is 0 month then put 1st month into tAge if tBirthDate = tToday then put born to day into tAge -- put tAge into fld sonAge end monthsCount on yearsCount set the itemDelimiter to slash put item 3 of tToday - item 3 of tBirthDate into tYearsNbr switch case item 1 of tToday item 1 of tBirthDate put tYearsNbr - 1 into tAge break case item 1 of tToday = item 1 of tBirthDate if item 2 of tToday item 2 of tBirthDate then put
Re: Age Anniversary Calculations
Here's what I use for #1: function doAge tDate,asOf -- return the age given birthdate = tDate -- as of the date asOf (if empty, assumes today) convert tDate to dateItems if asOf = empty then put the date into asOf end if convert asOf to dateitems put item 1 of asOf - item 1 of tDate - 1 into tAge put item 1 of asOf into item 1 of tDate convert tDate to seconds convert asOf to seconds if tDate = asOf then add 1 to tAge return tAge end doAge -- Peter Peter M. Brigham pmb...@gmail.com http://home.comcast.net/~pmbrig On May 21, 2012, at 3:02 AM, Igor de Oliveira Couto wrote: Dear LC Folks, What is the 'best' way to perform these 2 calculations with LiveCode? 1) Calculate a person's age, given a birthdate: /* Calculates the number of birthdays from a given date, up to and including *today*. @param pBirthDate the birthdate @return a positive integer representing the number of birthdays from pBirthDate to today. */ function currentAge pBirthDate ...? end currentAge 2) Calculate whether an *anniversary* falls within a time frame - ie., within a week, within 2 weeks, within a month of today: /* Determines whether an anniversary date is close to a 'reference date'. @param pAnniversaryDate the anniversary date @param pReferenceDate the date that is supposed to be 'close' - or not - to the anniversary date @pTimeFrame a time period, in seconds, that determines what 'close' is: it can be 1 day, 7 days, 1 month, etc. @return a boolean: if the anniversary date is sufficiently 'close' (as specified by pTimeFrame) to the reference date, then it returns TRUE, otherwise it returns FALSE. */ function isAnniversaryClose pAnniversaryDate, pReferenceDate, pTimeFrame ...? end isAnniversaryClose I'm not being lazy, but the algorithms I came up with look so 'convoluted' that I *know* there must be an easier way. I know that usually in every language there is a 'standard' or 'best-practice' way to perform these standard date calculations, so rather than re-inventing the wheel, I thought I'd run it by you, Masters, and be humbled by your experience! :-) Many thanks in advance, -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode
Re: Age Anniversary Calculations
Wasn't there a recent post that indicated this would not work? Anything before a certain date (I forget what it was) would be a day off? Bob On May 21, 2012, at 9:38 AM, Peter M. Brigham, MD wrote: Here's what I use for #1: function doAge tDate,asOf -- return the age given birthdate = tDate -- as of the date asOf (if empty, assumes today) convert tDate to dateItems if asOf = empty then put the date into asOf end if convert asOf to dateitems put item 1 of asOf - item 1 of tDate - 1 into tAge put item 1 of asOf into item 1 of tDate convert tDate to seconds convert asOf to seconds if tDate = asOf then add 1 to tAge return tAge end doAge -- Peter Peter M. Brigham pmb...@gmail.com http://home.comcast.net/~pmbrig On May 21, 2012, at 3:02 AM, Igor de Oliveira Couto wrote: Dear LC Folks, What is the 'best' way to perform these 2 calculations with LiveCode? 1) Calculate a person's age, given a birthdate: /* Calculates the number of birthdays from a given date, up to and including *today*. @param pBirthDate the birthdate @return a positive integer representing the number of birthdays from pBirthDate to today. */ function currentAge pBirthDate ...? end currentAge 2) Calculate whether an *anniversary* falls within a time frame - ie., within a week, within 2 weeks, within a month of today: /* Determines whether an anniversary date is close to a 'reference date'. @param pAnniversaryDate the anniversary date @param pReferenceDate the date that is supposed to be 'close' - or not - to the anniversary date @pTimeFrame a time period, in seconds, that determines what 'close' is: it can be 1 day, 7 days, 1 month, etc. @return a boolean: if the anniversary date is sufficiently 'close' (as specified by pTimeFrame) to the reference date, then it returns TRUE, otherwise it returns FALSE. */ function isAnniversaryClose pAnniversaryDate, pReferenceDate, pTimeFrame ...? end isAnniversaryClose I'm not being lazy, but the algorithms I came up with look so 'convoluted' that I *know* there must be an easier way. I know that usually in every language there is a 'standard' or 'best-practice' way to perform these standard date calculations, so rather than re-inventing the wheel, I thought I'd run it by you, Masters, and be humbled by your experience! :-) Many thanks in advance, -- Igor Couto Sydney, Australia ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode ___ use-livecode mailing list use-livecode@lists.runrev.com Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-livecode