I have the below
private function yearMenu() {
$m = date('m');
$y = date('Y');
if (($m>3 && $y==2019) || ($m<4 && $y==2020)){
$menu = 1;
}
if (($m>3 && $y==2020) || ($m<4 && $y==2021)){
$menu = 2;
}
if (($m>3 && $y==2021) || ($m<4 && $y==2022)){
$menu = 3;
}
if (($m>3 && $y==2022) || ($m<4 && $y==2023)){
$menu = 4;
}
if (($m>3 && $y==2023) || ($m<4 && $y==2024)){
$menu = 5;
}
if (($m>3 && $y==2024) || ($m<4 && $y==2025)){
$menu = 6;
}
return $menu;
}
This code works as intended i.e. I want to be able to give each financial year an integer based on 2019-2020 being the base at value 1 and it increasing each year onward
I was wondering if there was a more succinct and scalable way to do this?
Thanks
2 Answers 2
Ways of improving:
According to information provided the crucial function's purpose is "to return a particular menu number for the current year". Thus, the function name would be more descriptive with name getFinYearMenuNumber
.
The preconditions are:
- your financial year flows through "April to April" month periods
there's starting year
2019
and ending year2015
for the whole interval.
To make the function more unified those boundaries could be passed as input parameters:function getFinYearMenuNumber($yearFrom, $yearTo)
The main issue of the current approach is that it'll inevitably perform 5 excessive if
checks (they could be at least mutually exclusive if ... else if ... else if ...
).
Instead, we can just perform 2 subsequent checks:
- if the current year falls in the needed interval
- if the current month is following or preceding the starting month (April)
The final version:
function getFinYearMenuNumber($yearFrom, $yearTo) {
$curr_month = (int) date('m'); # current month number
$curr_year = (int) date('Y'); # current year
$curr_date = new DateTime();
if ((new DateTime("$yearFrom-04")) <= $curr_date && $curr_date <= (new DateTime("$yearTo-04"))) {
if ($curr_month > 3) {
return $curr_year - $yearFrom + 1;
} else if ($curr_month < 4) {
return $curr_year - $yearFrom;
}
}
return 0;
}
print_r(getFinYearMenuNumber(2019, 2025));
Your current version is very much a fixed piece of code, as you can see there is a lot of repetition and the result can be summed up as
- Based on 2019年04月01日 being the start of the first year
- The year counting up as starting on the 4th month of each year.
This code is very much based on that premise, taking the start date (an optional parameter to this method - defaulted to current date) the code takes the difference between the date to test and the date of 2019年04月01日 (using diff()
). This returns an instance of DateInterval
, which you can then extract the year component (y
) and add 1 so that 2019 is year 1.
(Altered to be a standalone function for test purposes)...
function getFinanceYear ( DateTime $dateToTest = null) {
// Use date passed in, or default to current date
$dateToTest = $dateToTest ?? new DateTime();
// Calculate the difference
$interval = $dateToTest->diff(new DateTime("2019-04-01"));
// return the difference in years (offset by 1)
return $interval->y+1;
}
A few test runs...
echo getFinanceYear().PHP_EOL; // 1
echo getFinanceYear(new DateTime("2029-03-01")).PHP_EOL; // 10
echo getFinanceYear(new DateTime("2029-04-01")).PHP_EOL; // 11
-
\$\begingroup\$ Excellent, succinct, scalable, and unconditional (in its calculation). \$\endgroup\$mickmackusa– mickmackusa2019年11月15日 22:19:34 +00:00Commented Nov 15, 2019 at 22:19