Recommended Free Tools
To select the range from the previous year through the current year, build that two-year value and compare it with each option. For example, when the current year is 2024, the selected option should be 2023-2024. Use one explicit timezone and one captured current date so the options and selection agree.
Generate and select the year range
This example lists calendar-year ranges starting at 2020 and ending in the current year. The final option is therefore the previous-year/current-year pair.
<?php
$now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$currentYear = (int) $now->format('Y');
$firstYear = 2020;
$selectedRange = ($currentYear - 1) . '-' . $currentYear;
?>
<select name="year_range">
<?php for ($year = $firstYear; $year < $currentYear; $year++):
$range = $year . '-' . ($year + 1);
$selected = ($range === $selectedRange) ? ' selected' : '';
?>
<option value="<?= htmlspecialchars($range, ENT_QUOTES, 'UTF-8') ?>"<?= $selected ?>>
<?= htmlspecialchars($range, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endfor; ?>
</select>
With a current year of 2024, the loop produces ranges from 2020-2021 through 2023-2024, and marks 2023-2024 as selected. The strict comparison works because both values use the same year-year format.
Choose the timezone that defines “current year”
The example uses UTC as an explicit choice, not a requirement for every application. PHP’s date() uses the default timezone when no timestamp is supplied; see the PHP date() manual. For timezone-aware date handling, PHP recommends using DateTimeImmutable with a timezone attached; the date and time documentation notes that “Unix timestamps do not handle timezones.”
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems#1 Best Overall
Replace UTC with the timezone your application uses, for example America/New_York. Deriving the current year once from a single DateTimeImmutable value also avoids calculating the range and selected value from separate reads that could fall on opposite sides of a year boundary.
Set the range boundaries to match the intended options
- Only ranges ending in the current year: Use
$year < $currentYearas in the example. - Include a range ending next year: Change the loop condition to
$year <= $currentYear. That adds a future-ending option such as2024-2025when the current year is 2024; it does not change the selected previous/current pair. - Use a different starting year: Set
$firstYearto the earliest starting year you want listed.
The SitePoint question’s clarification specifies a previous-year/current-year selection, but does not establish whether the options should represent calendar years, school years, or fiscal years. If the period starts on a date other than January 1, define how the application determines its period before calculating the selected option.
Rank #2
Why a two-value range is not enough
range(date("Y") - 1, date("Y")) returns the two year numbers. It does not by itself create combined labels such as 2023-2024 or select the matching dropdown option. Build the pair for each option, then compare it with the selected pair, as the code above does. The original question and clarification are in the SitePoint Forums thread.
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.




