To automatically select the range from the previous calendar year through the current year, build that combined value in PHP and compare it with each option’s value. For example, if the current year is 2024, the selected option should be 2023-2024. Choose the timezone that defines “current year” for your application, because that choice controls when the range rolls over.
Generate and select the year range
This example lists calendar-year ranges from 2020 through the range ending in the current year. It uses one captured time in UTC so the current year and selected value come from the same moment. Change UTC if your application uses another timezone.
<?php
$now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$currentYear = (int) $now->format('Y');
$firstYear = 2020;
$selected = ($currentYear - 1) . '-' . $currentYear;
// Each option ends at the current year or earlier.
echo '<select name="year_range">';
for ($year = $firstYear; $year < $currentYear; $year++) {
$value = $year . '-' . ($year + 1);
$isSelected = ($value === $selected) ? ' selected' : '';
$escapedValue = htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
echo '<option value="' . $escapedValue . '"' . $isSelected . '>'
. $escapedValue
. '</option>';
}
echo '</select>';
?>
With a current year of 2024, this produces options from 2020-2021 through 2023-2024, with 2023-2024 selected. The loop stops before $currentYear because each option’s ending year is one greater than its starting year.
Set the timezone that defines “current year”
The example explicitly uses UTC. Replace it with the timezone that should govern the dropdown’s year boundary, such as the timezone relevant to your application’s users or reporting period. PHP’s date() uses the default timezone when no timestamp is supplied; the PHP date() manual documents that behavior. For timezone-aware date formatting, PHP recommends using DateTimeImmutable with a timezone attached; the PHP date and time documentation notes that Unix timestamps do not handle timezones.
#1 Best Overall
Capturing $now once also ensures the generated options and selected value use the same year if the code runs near midnight or a timezone’s year boundary.
Adjust the option range to fit your requirements
- Starting year: Set
$firstYearto the first range you want to offer. - End at the current year: Keep the loop condition
$year < $currentYear, as in the example. - Include a future-ending range: Use
$year <= $currentYearinstead. That adds a range from the current year to the next year, but it does not change the selected previous/current-year pair. - Use a different kind of period: If the options represent school or fiscal years rather than calendar years, define the relevant start and end years and the rollover rule explicitly. The forum question does not establish those rules.
Why compare the whole range?
The selected option is a pair, not a single year. Comparing the current year alone to an option value such as 2023-2024 will not match. Instead, create the selected pair with ($currentYear - 1) . '-' . $currentYear and compare it with the same combined value used for each option.
Rank #2
The original SitePoint discussion began with a single-year dropdown and later clarified the intended result: if the current year is 2024, select 2023-2024. Its SitePoint Forums thread suggested range(date("Y") - 1, date("Y")) for obtaining the two years. That range alone does not create paired labels or select the matching pair; the loop above handles both.
Quick Recap
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

