Posted on January 27th, 2007
27545 views
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:
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:
Let us now break this code into little pieces and try to understand it: First we have:
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.
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:
I think you got the general idea. If not then I suggest you read more on the explode() function on PHP.net
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".
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:
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:
This lines simply print the following:
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. |