Various online services have different values for maximum year of expiry, when it comes to Credit Cards.
For instance:
<?php
$y = gmdate("Y");
$x = 20;
$max = ($y + $x);
while ($y <= $max) {
echo "<option value='$y'>$y</option>";
$y = $y + 1;
}
?>
As a theoretical upper limit, I propose that you do not need to consider more than the expected lifespan of the cardholder. Wikipedia does this in their editorial standards for biographies of living persons:
Any individual born less than 115 years ago is covered by this policy unless a reliable source has confirmed the individual's death. People over 115 years old are presumed dead unless listed at oldest people.
So, in your code, look up the current year, add 115, and use that as your theoretical upper limit to the credit card expiration date. You'll never have to touch that code again.
After reading the OP's upper validity of 20 years for Amazon, I wrote this simple solution in PHP:
<select name='Expiry-Year'>
<option value="">yy</option>
<?php
for($i=0;$i<21;$i++){
echo "<option value='".(date('Y')+$i)."'>".(date('y')+$i)."</option>\n";
}
?>
</select>
This has greatly reduced the number of these new-year requests to remove last year
from a form.
A leaner version of the loop runs ~twice as quickly:
<select name='Expiry-Year'>
<option value="">yy</option>
<?php
for($i=date('Y');$i<date('Y')+21;$i++){
echo "<option value='".$i."'>".substr($i,2)."</option>\n";
}
?>
</select>
<script type="text/javascript">
var select = $(".card-expiry-year"),
year = new Date().getFullYear();
for (var i = 0; i < 20; i++) {
select.append($("<option value='"+(i + year)+"' "+(i === 0 ? "selected" : "")+">"+(i + year)+"</option>"))
}
</script>