Calculating Chinese zodiac signs based on birthdays
To start, lets look for something that we can loop through. From your link to relevant dates, we can see that the associated animals loop through 12 animals, in order:

Rat
Ox
Tiger
Rabbit
Dragon
Snake
Horse
Goat
Monkey
Rooster
Dog
Pig


After [Pig], it restarts again with [Rat]. So let's put these into an associative array, with the associated element:

$assocs = array(
    "Rat"     =&gt;  "Yang Wood", 
    "Ox"      =&gt;  "Yin Wood", 
    "Tiger"   =&gt;  "Yang Fire",
    "Rabbit"  =&gt;  "Yin Fire", 
    "Dragon"  =&gt;  "Yang Earth", 
    "Snake"   =&gt;  "Yin Earth", 
    "Horse"   =&gt;  "Yang Metal", 
    "Goat"    =&gt;  "Yin Metal", 
    "Monkey"  =&gt;  "Yang Water", 
    "Rooster" =&gt;  "Yin Water", 
    "Dog"     =&gt;  "Yang Wood", 
    "Pig"     =&gt;  "Yin Wood" )
);


Now, to determine the sexagenary cycle of a gregorian year, the algorightm is as follows:

sCycle = (grego - 3) - (60 X ([(grego - 3)] / 60))


So, let's translate that to a PHP function:

function sexagenaryToGregorian($gYear){
    return ($gYear - 3) - (60 * (floor(( $gYear - 3) / 60)));
}


Now, we know that the Sexagenary cycle consists of 60 periods, thus, to determine what animal and element a certain year matches:

$bdayYear = 1989;
$sYear = sexagenaryToGregorian($bdayYear);
// $sYear == 6


For birth year 1989, sYear should be period 6. Now, let's generate a function that will hold the animal-element array above ($assoc) and contain two loops. The outer loop will decrement through the ceiling of the sexagenarian cycle divided by 12, and the inner loop is a foreach() over the animal-element array. This method is accurate all the way back to 4AD. 

function generateAnimal($sexaCycle){
    $assocs = array(
        "Rat"     =&gt;  "Yang Wood", 
        "Ox"      =&gt;  "Yin Wood", 
        "Tiger"   =&gt;  "Yang Fire",
        "Rabbit"  =&gt;  "Yin Fire", 
        "Dragon"  =&gt;  "Yang Earth", 
        "Snake"   =&gt;  "Yin Earth", 
        "Horse"   =&gt;  "Yang Metal", 
        "Goat"    =&gt;  "Yin Metal", 
        "Monkey"  =&gt;  "Yang Water", 
        "Rooster" =&gt;  "Yin Water", 
        "Dog"     =&gt;  "Yang Wood", 
        "Pig"     =&gt;  "Yin Wood"
    );

    $i = 1;
    while(ceil($sexaCycle / 12) &gt; 0){
        foreach($assocs as $animal =&gt; $element){
            if($i == $sexaCycle)
                return array($animal =&gt; $element);
            $i++;
        }
    }
}


Let's give it a few runs:

// Let's find the result for the year 2041
$result = generateAnimal(sexagenaryToGregorian(2041));
print_r($result); // Array ( [Rooster] =&gt; Yin Water )

// Let's find the result for the year 4
$result = generateAnimal(sexagenaryToGregorian(4));
print_r($result); // Array ( [Rat] =&gt; Yang Wood )

// Let's find the result for the year 1989
$result = generateAnimal(sexagenaryToGregorian(1989));
print_r($result); // Array ( [Snake] =&gt; Yin Earth )


Looks good to me! Now, if you want to include the dates, that's when you may want to start thinking about just using a database as a static lookup table.