# PHP: Calculate Real Differences Between Two Dates or Timestamps - Comment Page: 4

I was using simple function to calculate difference between two dates and timestamps until I noticed, it's not working correctly in long intervals. It's very easy to calculate difference between two timestamps in seconds, but it's much more complicated print difference in human readable format. The Internet can be found in a wide range of ways to do this thing, but as a rule they use a fixed amount of seconds for the year and the month. So if we calculate year with using 365 or 365.25 days and month using 30 or 31 then the difference is not accurate, because of leap years, DST (Daylight Saving Time) and so on. Because of this problem, I decided to make a function (at least in the short...

## 226 comments on “PHP: Calculate Real Differences Between Two Dates or Timestamps - Comment Page: 4”

1 2 3 4 5 6 10
1. Hi,

This is a great code, and I like the way it drops the hours or minutes if it is zero. I want it to only show the biggest value, for example 4 minutes and 12 seconds, should only show 4 minutes, and 5 hours 24 minute 33 seconds should only show 5 hours.

For example on google news, and article was posted 3 days ago, or 5 hours ago. The accuracy below that is not needed.

Thanks
Dave.

2. I’ve just changed the precision to 1 and it works perfectly! Thanks very much for this code.

• Hi Dave,

Youâ€™re welcome and nice to hear that you got it to work the way you want!

3. hi JR,

this script is awesome, many thanks!

a question though, i can see how you remove the h/m/s, but is it possible to return just the number of days rather than years, months, days?

for example: ’45 days’ rather than ‘1 month 15 days’?

thanks!

steve.

• Hi steve,

Glad to hear that, you like this.

It’s actually very easy to remove years and months. You could modify \$instervals array, like following:

``````
// Original intervals array
\$intervals = array('year','month','day','hour','minute','second');

// Just days
\$intervals = array('day');

// Days, hours, minutes and seconds
\$intervals = array('day','hour','minute','second');
``````

One thing that may yet change is the following line:

``````
function dateDiff(\$time1, \$time2, \$precision = 6) {

// to
function dateDiff(\$time1, \$time2, \$precision = 1) {
// or
function dateDiff(\$time1, \$time2, \$precision = 4) {
``````

This is not mandatory (this does not break anything), but then final function looks better… ;)

4. The function doesn’t seem to like dates prior to 1970 (I guess).

I use it to determine age of people on a certain date, batches of 15-25 at a time. But the process increases significantly if dates are further away from (prior to) 1970.

5. Thanks for this. I was considering making a code to do the same thing but you have saved me lots of time and effort.

6. Hey JR, been a while since I’ve posted here… any way, I was wondering if you could help me with something. Below is the code used on my site and I was wondering if you could tell me what needs to be altered to number_format() the days so come the 3rd yr you wouldn’t see 1095 but instead would see 1,095.

Thx JR !

``` // Time format is UNIX timestamp or // PHP strtotime compatible strings function dateDiff(\$time1, \$time2, \$precision = 4) { // If not numeric then convert texts to unix timestamps if (!is_int(\$time1)) { \$time1 = strtotime(\$time1); } if (!is_int(\$time2)) { \$time2 = strtotime(\$time2); }```

``` // If time1 is bigger than time2 // Then swap time1 and time2 if (\$time1 > \$time2) { \$ttime = \$time1; \$time1 = \$time2; \$time2 = \$ttime; } // Set up intervals and diffs arrays \$intervals = array('Year', 'Day', 'Hour', 'Minute'); \$interval_names = array('Year' => 'Yr', 'Day' => 'Day', 'Hour' => 'Hr', 'Minute' => 'Min'); \$diffs = array(); // Loop thru all intervals foreach (\$intervals as \$interval) { // Set default diff to 0 \$diffs[\$interval] = 0; // Create temp time from time1 and interval \$ttime = strtotime("+1" . \$interval, \$time1); // Loop until temp time is smaller than time2 while (\$time2 >= \$ttime) { \$time1 = \$ttime; \$diffs[\$interval]++; // Create new temp time from time1 and interval \$ttime = strtotime("+1" . \$interval, \$time1); } } \$count = 0; \$times = array(); // Loop thru all diffs foreach (\$diffs as \$interval => \$value) { // Break if we have needed precission if (\$count >= \$precision) { break; } // Add value and interval // if value is bigger than 0 if (\$value > 0) { // Add if value is not 1 if (\$value != 1) { \$interval = \$interval_names[\$interval] . "s"; } else { \$interval = \$interval_names[\$interval]; } // Add value and interval to times array \$times[] = \$value . " " . \$interval; \$count++; } } // Return string with times return implode(", ", \$times); } // echo dateDiff(1267074000, time(), 4) . "\n"; function addOrdinalSuffix(\$number) { if (in_array((\$number % 100),array(11,12,13))){ return \$number.'th'; } else { switch ((\$number % 10)) { case 1: return \$number.'st'; break; case 2: return \$number.'nd'; break; case 3: return \$number.'rd'; break; default: return \$number.'th'; break; } } } \$birthday_date = '2010-02-25'; \$current_date = date('Y-m-d'); list(\$birthday_year, \$birthday_month, \$birthday_day) = explode("-", \$birthday_date); list(\$current_year, \$current_month, \$current_day) = explode("-", \$current_date); if (\$birthday_month == \$current_month && \$birthday_day == \$current_day) { echo 'Happy ', addOrdinalSuffix(\$current_year - \$birthday_year), ' B-Day myu2sig.com !'; echo "\n"; } ```

` else {echo dateDiff(1267074000, time(), 4) . "\n";}`

• Hi again Andy :)

I don’t fully understand that what you want to do because I can’t find number_format() function in your code.

Could you please try to explain a bit more detailed, so I can try to help you…

7. number_format() is not in the code, what I am saying is that I want to make the days figured be encased by it.

So come the 3rd yr you wouldnâ€™t see 1095 but instead would see 1,095.

As the code stands in it’s current format, shold 3 yrs go by you would see 1095 and thats just ugly to me.

Now do you get it ?

• Hi Andy,

Try following:

``````
// Change following line
\$times[] = \$value . " " . \$interval;

// To
\$times[] = number_format(\$value, 0, '.', ',') . " " . \$interval;
``````
8. @itsgreen – Anything prior to 1970/71 needs to be formatted like a negative number.

ex. -2204201921

That should allow this “script” to function with any date prior to 1970/71.

9. @itsgreen – Not sure if how you would do it but you could possibly code the “script” to add the – to the beginning of any timestamps that are prior to 1970 since in your case it sounds like your full on auto and not doing anything on a case by case basis.

10. @itsgreen and @andy

This function is designed to work only with UNIX timestamps, it’s reason why this is not working with anything prior 1970.

What is the UNIX time stamp?

The UNIX time stamp is a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970. Therefore, the unix time stamp is merely the number of seconds between a particular date and the Unix Epoch. This is very useful to computer systems for tracking and sorting dated information in dynamic and distributed applications both online and client side.

11. @JR – In regards to my comments to itsgreen, your script does accurately work with dates / timestamps prior to 1970. I tested this with something from the 1900’s and it worked great. You just need the – at the beginning of the timestamps to say ok, this is before 1970.

This is what I used to get a timestamp from the 1900’s which I then plugged in to your system and it worked out just fine.

Epoch & Unix Timestamp Conversion Tools

12. very nice read and function works like charm, thank you

13. Thx for this script. I am using it to show how soon an event is coming up, but when it passes it should show “Overdue”. Any ideas?

14. I figured it out:

// if same day
if (\$time1 == \$time2) {
echo “TODAY”;
}

// if past
if (\$time1 \$time2) {
\$ttime = \$time1;
\$time1 = \$time2;
\$time2 = \$ttime;
}