Pretty PHP Date Ranges
Posted on December 28, 2013
Last week I needed to come up with a way to display a pretty date range based on a starting and ending date in PHP. It’s simple enough use PHP’s date function to convert a unix timestamp into a pretty date format, but PHP doesn’t have a built in function to format date ranges.
The goal was to take two unix time stamps and output a range that looks like this:
January 25 – 26th, 2014
This sounds and is simple until you take into account that sometimes it crosses months and needs to look like this:
January 25 – February 2nd, 2014
or could cross years like this:
December 25th, 2013 – January 3rd, 2014
So here is the code to build those prettified date ranges:
* @since 1.0
*/
function jb_verbose_date_range($start_date = '',$end_date = '') {
$date_range = '';
// If only one date, or dates are the same set to FULL verbose date
if ( empty($start_date) || empty($end_date) || ( date('FjY',$start_date) == date('FjY',$end_date) ) ) { // FjY == accounts for same day, different time
$start_date_pretty = date( 'F jS, Y', $start_date );
$end_date_pretty = date( 'F jS, Y', $end_date );
} else {
// Setup basic dates
$start_date_pretty = date( 'F j', $start_date );
$end_date_pretty = date( 'jS, Y', $end_date );
// If years differ add suffix and year to start_date
if ( date('Y',$start_date) != date('Y',$end_date) ) {
$start_date_pretty .= date( 'S, Y', $start_date );
}
// If months differ add suffix and year to end_date
if ( date('F',$start_date) != date('F',$end_date) ) {
$end_date_pretty = date( 'F ', $end_date) . $end_date_pretty;
}
}
// build date_range return string
if( ! empty( $start_date ) ) {
$date_range .= $start_date_pretty;
}
// check if there is an end date and append if not identical
if( ! empty( $end_date ) ) {
if( $end_date_pretty != $start_date_pretty ) {
$date_range .= ' - ' . $end_date_pretty;
}
}
return $date_range;
}
Also available on GitHub/Gist here.
To actually use that in WordPress you’d just add something like this in your template file where you wanted to output the date, here based on two custom field values.
';
echo jb_verbose_date_range( $start_date , $end_date );
echo '';
}
Thanks very much!
Awesome! Glad it helped.
Wow, thanks for this! I wrote something similar but mine was 4 times longer haha Yours is much more efficient. I was wondering if you could help me, what would I need to change to get the following outputs... 23. June 2014 23. - 26. June 2014 23. June - 23. July 2014 23. June 2014 - 23. July 2015 So basically removing the "th", "st" etc.. and putting a "." then swapping the day before the month? Cheers, Brian
HA! Well I assume your my first draft of this was 4 times longer as well. So you just want to change things from: "F jS, Y" to "j.F Y" I suspect you're already familar but for others see: http://php.net/manual/en/function.date.php I think it'll just be a straight replacement in the lines building the string and the logic still will work. ie.leave the (if/then) conditionals as they are, but change things like
$start_date_pretty = date( 'F j', $start_date ); //to $start_date_pretty = date( 'j.F', $start_date );
When I pass dates to this function I only get a random date of December 31st, 1969. Code is below. // this is a while loop getting dates from db $start_date = $row['startDate']; $end_date = $row['endDate']; if ( (!empty($start_date)) || (!empty($end_date)) ) { echo "" ; echo jb_verbose_date_range( $start_date , $end_date ); echo ""; }
In what format are you storing the dates?
Originally they were of type 'date' in a mySQL DB but I changed them to a type of 'text' . Still didn't work.
Sorry I wasn't clear. I mean that function assumes it is given two unix time stamps. If you're saving the date as 2015-01-28 it's going to interpret incorrectly and probably give you wrong date. See the link above to the PHP date function.
Jon, Thanks! I formatted the date before sending it to your function. Looks great now!
Sorry to complain about freely shared code, but this would be more useful with a license specified. As is, I can't even look at the code legally. Bonus points if you toss it on Github!
lol... Didn't even think about it, but consider it WTFPL. I'll add that to the comment block and link to it as a Gist.
Modified slightly to add an optional separator string, defaults to em dash. I needed to change it to ' to ' in my project. /** * Verbose Beautified Date Range * * E.g., * January 25 – 26th, 2014 * January 25 – February 2nd, 2014 * December 25th, 2013 – January 3rd, 2014 * * @access public * @param mixed $start_date * @param mixed $end_date * @param mixed $separator * @return $date_range (beautified date range) * @license WTFPL * * @author Jon Brown * * @since 1.1.0 Added $separator param - Sam Sehnert * @since 1.0.0 Introduced - Jon Brown * * @see https://9seeds.com/tech/pretty-php-date-ranges/ */ function jb_verbose_date_range($start_date = '',$end_date = '', $separator = ' – ') { $date_range = ''; // If only one date, or dates are the same set to FULL verbose date if ( empty($start_date) || empty($end_date) || ( date('FjY',$start_date) == date('FjY',$end_date) ) ) { // FjY == accounts for same day, different time $start_date_pretty = date( 'F jS, Y', $start_date ); $end_date_pretty = date( 'F jS, Y', $end_date ); } else { // Setup basic dates $start_date_pretty = date( 'F j', $start_date ); $end_date_pretty = date( 'jS, Y', $end_date ); // If years differ add suffix and year to start_date if ( date('Y',$start_date) != date('Y',$end_date) ) { $start_date_pretty .= date( 'S, Y', $start_date ); } // If months differ add suffix and year to end_date if ( date('F',$start_date) != date('F',$end_date) ) { $end_date_pretty = date( 'F ', $end_date) . $end_date_pretty; } } // build date_range return string if( ! empty( $start_date ) ) { $date_range .= $start_date_pretty; } // check if there is an end date and append if not identical if( ! empty( $end_date ) ) { if( $end_date_pretty != $start_date_pretty ) { $date_range .= $separator . $end_date_pretty; } } return $date_range; }
Sorry, just realised it should default to en dash...
Thank you! This is exactly what I needed.
Thanks for saving me a bunch of time!
Glad to hear it!
This is great. Thanks so much. With a few modifications I was able to use it to produce the exact date formats I wanted.
Thanks for sharing this!