Publishing System Settings Logout Login Register
Calculate the number of days, weeks, years between two user inputted dates
TutorialCommentsThe AuthorReport Tutorial
Tutorial Avatar
Rating
Add to Favorites
Posted on January 27th, 2007
27545 views
PHP Coding
Introduction

This tutorial will teach you how to implement a function which calculates the number of days, weeks or years that have passed between two dates. Some of you who have some experience in C/C++/Pascal or any other programming language know that it can be a real pain in the arse to write an algorithm that does that. Well this is not the case in PHP because of the "miracle" of Unix Timestamp.

Unix Timestamp

The Unix Timestamp is a long integer containing the number of seconds between the Unix Epoch (January 1 1970 00:00:00 GMT) and the time specified. (from PHP.net)

So basically a timestamp is the number of seconds that have passed since January 1 1970. Why this date? Well to be honest I don't know for sure but I think it has something to do with the first Unix system. If you want to learn more on this then read Unix time.

The Function

Ok, now you may ask how is this going to help in finding the number of days (weeks and years) between two dates? Well, by applying some simple math it's easy.
Another thing you may be concerned now is "how exactly do we find the number of seconds since 1970?". Well you don't have to because the team that made PHP have made some really neat functions that do that for you. One of this functions, which is my personal favorite when it comes to dates, is mktime().
So before describing the algorithm let's take a look at this PHP function:

PHP mktime() function

mktime -- Get Unix timestamp for a date

Description:

int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )

Returns the Unix timestamp corresponding to the arguments given. This timestamp is a long integer containing the number of seconds between the Unix Epoch (January 1 1970 00:00:00 GMT) and the time specified.

Arguments may be left out in order from right to left; any arguments thus omitted will be set to the current value according to the local date and time.

To see the entire description of this function and also see what each parameter stands for read mktime on PHP.net

I think that by reading the description above you understand how to use this wonderful function, but just in case, here are some examples of how it works:


<?php

echo mktime(0, 0, 0, 12, 32, 1997); // Will print '883605600' which is the Timestamp for December 32, 1997, 00:00:00 GMT
echo mktime(0, 0, 0, 13, 1, 1997); // Will print 883605600
echo mktime(0, 0, 0, 1, 1, 1998); // Will print 883605600
echo mktime(0, 0, 0, 1, 1, 98); // Will 883605600
echo mktime(); // Will print 1169149635 which is the Timestamp for the current date

?>


Now that we know what this function does and how to use it let's start writing our own function that counts the number of days. I will first write the entire code and then break it up into pieces and explain it.
So here's the code:


<?php

$date = "01-16-2005"; // the format of this date is MM-DD-YYYY which is the American way of writing a date and the most common used on the internet
$currentDate = mktime();     // for the second date we are going to use the current Unix system time
                            // be advised that this is not necessarily the date of your computer but the date of the Unix server on which the .php file resides

$dateSplit = explode("-", $date); // see explanations below to see what this does

//$dateSplit[0] = Month
//$dateSplit[1] = Day
//$dateSplit[2] = Year

$previousDate = mktime(0, 0, 0, $dateSplit[0], $dateSplit[1], $dateSplit[2]); // we will now create the timestamp for this date

$nrSeconds = $currentDate - $previousDate; // subtract the previousDate from the currentDate to see how many seconds have passed between these two dates

$nrSeconds = abs($nrSeconds); // in some cases, because of a user input error, the second date which should be smaller then the current one
                            // will give a negative number of seconds. So we use abs() to get the absolute value of nrSeconds

$nrDaysPassed = floor($nrSeconds / 86400); // see explanations below to see what this does
$nrWeeksPassed = floor($nrSeconds / 604800); // same as above
$nrYearsPassed = floor($nrSeconds / 31536000); // same as above

echo $nrDaysPassed . " days have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";
echo $nrWeeksPassed . " weeks have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";
echo $nrYearsPassed . " years have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";

?>


Let us now break this code into little pieces and try to understand it:

First we have:


$date = "01-16-2005"; // the format of this date is MM-DD-YYYY which is the American way of writing a date and the most common used on the internet
$currentDate = mktime();     // for the second date we are going to use the current Unix system time
                            // be advised that this is not necessarily the date of your computer but the date of the Unix server on which the .php file resides


So, on the first line of the code we initialize the variable $date with a date. For the sake of this tutorial I decided to use a date written by me and not taken from a form as you would normally do on a interactive site. The format of the date is MM-DD-YYYY which is the American way of writing a date. I also chose this  because this is the only format I know that the function strtotime() doesn't recognize.

To learn more about strtotime() also read "Strings to Time with PHP's strtotime()" which is a great tutorial written by Chaos King


For those of you who are interesting in how to initialize the variable with a value taken from a form then you should replace this line with $date = $_POST['<field_name'];, where <field_name> is the name of the field in the form which holds the date. But that would be a whole new tutorial.

Ok, enough with the Tips & Tricks, let's move to the second line of code. On this line we initialize the variable $currentDate with the current Timestamp of the Unix system, taken with mktime() with no parameters. Of course, as said above, you can use any other date, as long as you transform it into a Unix Timestamp.


$dateSplit = explode("-", $date); // see explanations below to see what this does


Now, to understand this line you'll have to know what explode() those. So here's a short official explanation taken from PHP.net:


PHP explode() function

array explode ( string delimiter, string string [, int limit] )

Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter. If limit is set, the returned array will contain a maximum of limit elements with the last element containing the rest of string.

So what it basically does is that it takes a source string, which in our case is the $date variable ("01-16-2005"), and it tries to split it into an array using the given delimiter, which in our case is "-". Don't understand what I mean by that? Well here's what the variable $dateSplit holds if we would print it using the print_r() function:


echo "<pre>"; print_r($dateSplit); echo "</pre>";     // echo "<pre>" and echo "</pre>" will echo the HTML tag so that the browser
                                                    //will show the result in a readable fashion.
                                                    //Try to echo without the <pre> tag and see what happens.

/*The output will be:

Array
(
    [0] => 01
    [1] => 16
    [2] => 2005
)*/


I think you got the general idea. If not then I suggest you read more on the explode() function on PHP.net


$previousDate = mktime(0, 0, 0, $dateSplit[0], $dateSplit[1], $dateSplit[2]); // we will now create the timestamp for this date


It should be obvious by now what this line of code does. It simply uses mktime() to initialize $previousDate with the Unix timestamp of the given date, which is "01-16-2005".


$nrSeconds = $currentDate - $previousDate; // substract the previousDate from the currentDate to see how many seconds have passed between these two dates

$nrSeconds = abs($nrSeconds); // in some cases, because of a user input error, the second date which should be smaller then the current one
                            // will give a negative number of seconds. So we use abs() to get the absolute value of nrSeconds


This is just simple mathematics. We subtract the previous date from the current date so that we can find the difference in seconds between them. Why is the result in seconds? Because both variables hold Unix timestamps which are in seconds. See beginning of tutorial for explanation in case you skipped it.

Normally, the current date should be bigger then the previous one but just in case a human input error occurs, we find the absolute value of $nrSeconds and save it (line 3 of the code above). So in case $nrSeconds is a negative number, say -23564, it will turn into 23564.

Of course that you could normally use a simple if clause to check if $nrSeconds is a positive number and if not print an error, but I took this opportunity to also explain to how to use the abs() function.

Now let's move to the next part of the code:


$nrDaysPassed = floor($nrSeconds / 86400); // see explanations below to see what this does
$nrWeeksPassed = floor($nrSeconds / 604800); // same as above
$nrYearsPassed = floor($nrSeconds / 31536000); // same as above


This is where all the computation is done. You may ask what with all those weird numbers? Well those are the number of seconds that correspond to a day, a week and respectively, a year. How I know that? Well through some simple mathematics. We all know that 60 seconds = 1 minute, 60 minutes = 1 hour, 24 hours = 1 day. So we multiply 60*60*24 and we find the number of seconds a day has, which is 86,400 seconds. We also know that 7 days = 1 week, so we multiply 60*60*24*7 and we get 604,800 which is the number of seconds a week has. And finally, we know that 365 days = 1 year (don't bug me about the leap years on this :)) so, by applying the same formula, 60*60*24*365, we get that 1 year has 31,536,000 seconds.

So how do we use these numbers to find the actual number of days? We simply divide $nrSeconds by the corresponding number of seconds of a day, a week and a year. But chances of getting an integer number when dividing are pretty small. So this is where floor() comes in handy.

float floor ( float value )

Returns the next lowest integer value by rounding down value if necessary. The return value of floor() is still of type float because the value range of float is usually bigger than that of integer.

So if after the division we have, let's say, 234.324, after applying floor() to this number we will get 234. Cool, isn't it?

Now, in the last lines of this code we have:


echo $nrDaysPassed . " days have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";
echo $nrWeeksPassed . " weeks have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";
echo $nrYearsPassed . " years have passed between " . date("F j, Y", $previousDate) . " and " . date("F j, Y", $currentDate) . "<br />";


This lines simply print the following:


732 days have passed between January 16, 2005 and January 18, 2007
104 weeks have passed between 1105826400 and 1169155496
2 years have passed between 1105826400 and 1169155496


So you can see that between the dates that we have selected, 732 days have passed or 104 full weeks or 2 full years.

Well that's the end of this tutorial. I hope you enjoyed it as much as I did when writing it and I hope that you will make use of the cool "Vote" feature that P2L has implemented. I would really love to see what you think of this tutorial, and the only way to do it is by either Voting the the tutorial or Comment or send me a  PM or by coming and saying hello to me on my Forum.

Have a nice day.
Dig this tutorial?
Thank the author by sending him a few P2L credits!

Send
Victor

I'm a student from Romania with 2 years experience in PHP, MySQL, HTML and CSS. I also have 5 years of Photoshop and 3D Studio Max experience which I basically use when designing and coding websites. I also run my own site which I encourage you to check o
View Full Profile Add as Friend Send PM
Pixel2Life Home Advanced Search Search Tutorial Index Publish Tutorials Community Forums Web Hosting P2L On Facebook P2L On Twitter P2L Feeds Tutorial Index Publish Tutorials Community Forums Web Hosting P2L On Facebook P2L On Twitter P2L Feeds Pixel2life Homepage Submit a Tutorial Publish a Tutorial Join our Forums P2L Marketplace Advertise on P2L P2L Website Hosting Help and FAQ Topsites Link Exchange P2L RSS Feeds P2L Sitemap Contact Us Privacy Statement Legal P2L Facebook Fanpage Follow us on Twitter P2L Studios Portal P2L Website Hosting Back to Top