So, I needed to do a comparison on age for my Facebook implementation. The problem is that Facebook only returns “birthday” in the format “August 31, 1984″ or “August 31″ if the year is hidden rather than returning the age directly. At first, I did the logical thing and wrote a short bit of code that got the birthday string, split the string in code and then checked the component parts to build the age. Here is my basic code for that:
That may be a bit hard to understand without getting the underlying model, but I think the gist of it can be gotten pretty easily (if you know how to program that is).
Of course, then I decided to be CUTE. I thought “you know FQL has some functions that I can use. I bet I can verify if the user is a certain age in FQL”. Sure I thought it would be a bit hard because I’d have to do the month word to month number conversion and have to split the string into the component pieces, but I am sure it is possible. An hour later, I had this monstrosity.
$current_year = intval(date("Y"));
$current_month = intval(date("m"));
$current_day = intval(date("d"));
$query = <<
select uid from user where uid = $this->application_user_id and strpos(birthday,”,”) > 0 and (
(($current_year-substr(birthday,strpos(birthday,”,”)+2,4) = $this->value) and (
(substr(birthday,0,strpos(birthday,” “)) == “January” and ($current_month > 1 or ($current_month = 1 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “February” and ($current_month > 2 or ($current_month = 2 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “March” and ($current_month > 3 or ($current_month = 3 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “April” and ($current_month > 4 or ($current_month = 4 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “May” and ($current_month > 5 or ($current_month = 5 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “June” and ($current_month > 6 or ($current_month = 6 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “July” and ($current_month > 7 or ($current_month = 7 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “August” and ($current_month > 8 or ($current_month = 8 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “September” and ($current_month > 9 or ($current_month = 9 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “October” and ($current_month > 10 or ($current_month = 10 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “November” and ($current_month > 11 or ($current_month = 11 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “December” and ($current_month > 12 or ($current_month = 12 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “)))))
))
or
(($current_year-substr(birthday,strpos(birthday,”,”)+2,4) = $this->value+1) and not (
(substr(birthday,0,strpos(birthday,” “)) == “January” and ($current_month > 1 or ($current_month = 1 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “February” and ($current_month > 2 or ($current_month = 2 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “March” and ($current_month > 3 or ($current_month = 3 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “April” and ($current_month > 4 or ($current_month = 4 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “May” and ($current_month > 5 or ($current_month = 5 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “June” and ($current_month > 6 or ($current_month = 6 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “July” and ($current_month > 7 or ($current_month = 7 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “August” and ($current_month > 8 or ($current_month = 8 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “September” and ($current_month > 9 or ($current_month = 9 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “October” and ($current_month > 10 or ($current_month = 10 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “November” and ($current_month > 11 or ($current_month = 11 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “))))) or
(substr(birthday,0,strpos(birthday,” “)) == “December” and ($current_month > 12 or ($current_month = 12 and $current_day >= substr(birthday,strpos(birthday,” “),strpos(birthday,”,”)-strpos(birthday,” “)))))
))
)
FACEBOOKAGEQUERY;
$results = $this->facebook->api_client->fql_query($query);
if($results == NULL)
return false;
else
return true;
It actually *does* work, but the problem is that if it needs to be called more than once on a page, it hangs up the page loading. I guess Facebook is like “wtf” at such a huge query. The important lesson? Yes, it is better to do something in SQL/FQL to save slower code normally, but if you are going to have to write a terribly inefficient query the savings of doing it on a faster server do not make up for the horrendous asymptotics introduced.
For what it’s worth, the basic format of the query is “if the user has the year field set, we check to see if this year minus the year the user is born is equal to the target age. If that is true, then it means the user will be turning the target age this year. In that case, we check to see if the user’s birthday has passed. If that is so, then we are good. If that is not so then we check to see if this year minus the year the user is born is equal to one year greater than the target age. If that is ture, then it means the user will turn the age past the target age this year. In that case, we check to see if the user has not had his birthday yet. If that is so, then we are good. If not, then the check returns no results.