patternphpMinor
Formatting a date range, with shortening if the interval falls entirely within a calendar month
Viewed 0 times
formattingentirelytheshorteningwithrangeintervaldatewithinmonth
Problem
The graphic guy wants to display dates like
Here is my solution:
I'm wondering if the this comparison:
is the best way to check whether
(
16. February
17. - 24. February, or
25. February - 02. March.
Here is my solution:
$d1 = new \DateTime('2015-02-06');
$d2 = new \DateTime('2015-03-02');
$dateDiff = $d1->diff($d2);
if (intval($dateDiff->d) != 0) {
$d = $d1->format('d.') . ' ' . ($d1->format('m') != $d2->format('m') ? $d1->format('F') : '') . ' - ' . $d2->format('d. F');
} else {
$d = $d1->format('d. F');
}I'm wondering if the this comparison:
$d1->format('m') != $d2->format('m')is the best way to check whether
$d1 and $d2 are in the same or different months.(
$dateDiff = $d1->diff($d2) tells me that the two dates are 24 days apart, but it doesn't tell me if they are in different calendar months.)Solution
This is a self-contained problem, with well-defined inputs and outputs. To be maintainable, the code should reside in a function.
You have three distinct cases, and maybe more:
Your solution should therefore be written to make it obvious that there are more than two cases.
Bugs in your implementation
Similarly,
Suggested solution
You have three distinct cases, and maybe more:
- Start and end dates are the same day
- Start and end dates fall in the same calendar month
- Start and end dates span calendar months
Your solution should therefore be written to make it obvious that there are more than two cases.
Bugs in your implementation
intval($dateDiff->d) != 0 is an invalid check. You would be treating the range from 2015-01-22 to 2015-03-22 as if it were one day.Similarly,
$d1->format('m') != $d2->format('m') is not quite right either. It would be deceptive to format the range from 2014-12-26 to 2015-12-25 as 26. – 25. December. It might be acceptable to say 26. December – 25. December. But really, it would be clearest to include the years as well.Suggested solution
function formatDateRange($d1, $d2) {
if ($d1->format('Y-m-d') === $d2->format('Y-m-d')) {
# Same day
return $d1->format('d. F');
} elseif ($d1->format('Y-m') === $d2->format('Y-m')) {
# Same calendar month
return $d1->format('d.') . $d2->format(' – d. F');
} elseif ($d1->format('Y') === $d2->format('Y')) {
# Same calendar year
return $d1->format('d. F') . $d2->format(' – d. F');
} else {
# General case (spans calendar years)
return $d1->format('d. F Y') . $d2->format(' – d. F Y');
}
}Code Snippets
function formatDateRange($d1, $d2) {
if ($d1->format('Y-m-d') === $d2->format('Y-m-d')) {
# Same day
return $d1->format('d. F');
} elseif ($d1->format('Y-m') === $d2->format('Y-m')) {
# Same calendar month
return $d1->format('d.') . $d2->format(' – d. F');
} elseif ($d1->format('Y') === $d2->format('Y')) {
# Same calendar year
return $d1->format('d. F') . $d2->format(' – d. F');
} else {
# General case (spans calendar years)
return $d1->format('d. F Y') . $d2->format(' – d. F Y');
}
}Context
StackExchange Code Review Q#78295, answer score: 6
Revisions (0)
No revisions yet.