Bad Age Check - I got Carded!
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-07-2006 15:29
I was going through the following piece of code, using it as a refference to write a function that does the same thing, but in a slightly different way.. and I came across something. First the code, which is from the newbieNag script available in the wikki library // Return number of days since 2000-01-01 integer datestamp(integer year, integer month, integer day){ year = year - 2000; list monthdays = [0,31,28,31,30,31,30,31,31,30,31,30,31]; integer i=1; integer sum = year * 365 + (year/4) + day; for(i=1;i<month;i++){ if( (month != 2) || (year % 4 != 0)){ sum+=llList2Integer(monthdays,month); }else if(month == 2){ sum+=29; } } if(year % 4 == 0){ return sum - 1; } return sum; }
Notice, he sets up a for statement using for (i=1; i<month; i++) but then he never uses it inside the code block. he keeps reffering to the variable 'month' which never changes. Now, I havn't taken this piece of code into the game to try it, but I'm willing to be this code doesn't work. I've made a couple changes in the version I have, which I have yet to take into game and test, but I think this may work better: // fncGetDays takes a single string in the form of "YYYY-MM-DD" and returns // the number of days from "2000-01-01" untill the provided date. It does // take into account leap years. integer fncGetDays(string strDate) { list lstMDays = [0,31,28,31,30,31,30,31,31,30,31,30,31]; // Used to get days of each month list lstDate = llParseString2List(strdate, ["-"], []); // Parse the date into segments integer intYear = (integer)llList2String(lstDate, 0); integer intMonth = (integer)llList2String(lstDate, 1); integer intDay = (integer)llList2String(lstDate, 2); intYear = intYear - 2000; // I doubt anyone here dates back to B.C. integer intSum = (intYear * 365) + (intYear / 4) + intDay; for (x = 1; x < intMonth; x++) { if ((x != 2) || ((intYear % 4) != 0)) // It isn't February of a Leap Year { intSum = intSum + llList2Integer(lstMDays, x); } else // It is February of a Leap Year { intSum = intSum + 29; } } if ((intYear % 4) == 0) // If we're in first 2 months of a Leap Year { return intSum - 1; } return intSum; }
Is it possible for someone to go update that script? Note: I do have to test it. That last part about returning intSum - 1, i'm not completely sure why it's there. I'll have to write a script to test what would happen if I didn't do that. Edit: Ok, just occured to me why we're subtracting the 1.. the 1 was added in the line integer intSum = (intYear * 365) + (intYear / 4) + intDay; and likely added again in the for loop. So we need to subract the 1. I also changed it back from if ((intYear % 4) == 0 && (intMonth =< 2)) to if ((intYear % 4) == 0) That makes sense to me now.
|
|
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
|
Date Conversions
09-07-2006 17:06
It doesn`t work, but not for the reason you`re thinking. I was looking for this code myself, and I ended up rewriting javascript I found on a webpage. integer isLeapYear(integer Year) {return ((Year % 4 == 0) && (Year % 100 != 0)) || (Year % 400 == 0);} integer dateVector2Integer(vector Date) { // Usage: // DateStamp = dateVector2Integer(<Year, Month, Day>); integer Year = (integer)Date.x; integer Days = Year * 365 + Year/4 - Year/100 + Year/400; Days += llList2Integer([0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], (integer)Date.y); if (Date.y >2) Days += isLeapYear(Year); return Days; }This isn`t an issue for most of us, but the formula used in the fisrt script you posted breaks for dates more than 99 years ahead or behind 2000. Now, if anyone can find any errors in MY script frag, I`d like to hear about them, and if you USE my functions, I would appreciate credit. For what it`s worth, I translated it from Online Conversion - Determine Day and Week Number.
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-07-2006 18:12
ok.. I don't expect to be passing any dates that are prior to 2000, for two reasons. First, when comparing today's date, I can Guarantee it's post 2000, since I'm writing this script in 2006. And since SL opened in 2003, I am quite sure I'm not going to find any people who's avatar was born prior to then. I know the irregularity that your code is trying to protect against. The current leapyear system has three rules: Years divisble by 4 are Leap years Years divisible by 100 are NOT Leap years Years divisible by 400 ARE Leap years The next time that this paticular irregularity in the leap year system will occur is in the year 2100 which is NOT a leapyear. I highly doubt that SL much less My script will still be in use by that year. If SL is still going strong by then, I'm sure it will have had enough changes that the code above would certainly not work. My code is good enough for this case. However, the usage of the list that your code does of listing all days up to the month in question, instead of stepping through a for loop is intriging, and I may try to use something similar.. Keeping in mind that I still gotta check for leap year and add one day for that. Edit: Ok, now my function looks like this. This is better yet, and credit is given. // fncGetDays takes a single string in the form of "YYYY-MM-DD" and returns // the number of days from "2000-01-01" untill the provided date. It does // take into account leap years. integer fncGetDays(string strDate) { // list lstMDays = [0,31,28,31,30,31,30,31,31,30,31,30,31]; // Used to get days of each month // This next line saves me having to use a for loop. Credit goes to Llauren Mandelbrot from the // SL Scripting Tips forum for this idea. list lstMDays = [0,0,31,59,90,120,151,181,212,243,273,304,334]; list lstDate = llParseString2List(strdate, ["-"], []); // Parse the date into segments integer intYear = (integer)llList2String(lstDate, 0); integer intMonth = (integer)llList2String(lstDate, 1); integer intDay = (integer)llList2String(lstDate, 2); intYear -= 2000; // I doubt anyone here dates back to B.C. integer intSum = (intYear * 365) + (intYear / 4) + intDay; if (((intYear % 4) == 0) && (intMonth <= 2)) // if leapday is later this year { intSum -= 1; // Then we added 1 too many above } intSum += (lstMDays, intMonth); // Add the days for previous months // for (x = 1; x < intMonth; x++) // { // if ((x != 2) || ((intYear % 4) != 0)) // It isn't February of a Leap Year // { // intSum = intSum + llList2Integer(lstMDays, x); // } // else // It is February of a Leap Year // { // intSum = intSum + 29; // } // } return intSum; }
The commented out section is left just in case I need to revert back to it. But chances are i'll delete that section later.
|
|
Llauren Mandelbrot
Twenty-Four Weeks Old.
Join date: 26 Apr 2006
Posts: 665
|
09-07-2006 20:14
You`re welcome.
|
|
Allan Saltwater
Verified Resident of SL
Join date: 20 Oct 2006
Posts: 36
|
01-17-2007 13:28
How about this for a modified form? // fncGetDays takes a single string in the form of "YYYY-MM-DD" and returns // the number of days from "2000-01-01" untill the provided date. It does // take into account leap years. integer fncGetDays(string strDate) // Works on Gregorian calendar from 1/3/1900 to 28/2/2100 // Works on Julian calendar from 1/1/1 (there was no "year zero", 1 BC was the year before AD 1) { // SL Scripting Tips forum for this idea. list lstDate = llParseString2List(strdate, ["-"], []); // Parse the date into segments integer intYear = (integer)llList2String(lstDate, 0); integer intMonth = (integer)llList2String(lstDate, 1); integer intDay = (integer)llList2String(lstDate, 2); if (intMonth <= 2) // make year Mar - Feb, Months 0 - 11 { intMonth += 9; intYear--; } else { intMonth -= 3; };
return (intYear * 1461) /4 + intDay + (intMonth * 306 - 1) / 10 - 730500; // 1461 days in 4 years (feb 29th last day of every 4th year) // the last part converts intMonth into 0,31,61,92,122,153,184,214,245,275,306,337 // 730500 days in 2000 years }
No array lookup, no loop less code. Modified from code used at job intrerview.
|
|
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
|
Astronimical Julian Dates
01-17-2007 13:58
/54/fe/136538/1.htmlMuch the same thing and some similar code... including the code to go back the other way.
|
|
Angel Fluffy
Very Helpful
Join date: 3 Mar 2006
Posts: 810
|
01-18-2007 18:15
From: Aakanaar LaSalle ok.. I don't expect to be passing any dates that are prior to 2000, for two reasons. First, when comparing today's date, I can Guarantee it's post 2000, since I'm writing this script in 2006.
That works so long as you don't somehow end up doing checks on Linden accounts (e.g. Phoenix Linden). You probably won't be able to look up data for Linden accounts anyway, as it is very hard to get their agent keys (they don't show up in sensor calls, I find).
_____________________
Volunteer Portal (FAQs!) : https://wiki.secondlife.com/wiki/Volunteer_Portal
JIRA / Issue Tracker : http://jira.secondlife.com (& http://tinyurl.com/2jropp)
|
|
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
|
01-19-2007 04:15
From: Angel Fluffy it is very hard to get their agent keys http://w-hat.com/lindens.txt 
|
|
Angel Fluffy
Very Helpful
Join date: 3 Mar 2006
Posts: 810
|
01-19-2007 04:59
Hunh. I had no idea that existed. I'd have thought getting the Lindens' keys would be hard, as they don't seem to show up on agent sensors, and it would be tedious to go around asking them to click key-getting scripts. I guess either there is an easier way of doing it (not the debug/IM panel way), or someone has a lot of time on their hands, or its important for some reason.
_____________________
Volunteer Portal (FAQs!) : https://wiki.secondlife.com/wiki/Volunteer_Portal
JIRA / Issue Tracker : http://jira.secondlife.com (& http://tinyurl.com/2jropp)
|