![]() |
Timezone Class: Dealing with Timezones the Proper Way
1 Attachment(s)
I must admit that I was going to write you a simple timezone script and then tell you how easy it was. However, I came across some handy timezone_* functions and things got a little more difficult but a lot more practical. This script will allow you to display the time in any timezone you wish, without any ifs, buts or maybes along the way.
This is the code I was going to use: php Code:
You can quite clearly see for yourself that it's a small function, however there are a couple of glaring problems with it. I realised the problems as I was coding the revised version and, although it would not be too difficult to fix, if you can do it a better way, then why not! I think it takes a brave coder to analyse and shred their own code into millions of parts, but here goes. I have spotted two immediate problems with the above:
With that script safely cast aside, allow us to move onto the new all singing, all dancing, script that will revolutionise the way you deal with timezones. Really! We're going to begin the script with our obligatory defines. Although these are not required in the least, they help us to visualise the system in an article, and that's the only real reason I use them. We will start off by supporting 3 timezones. These are as follows: php Code:
Once we have our defines in place we can begin our function. We're going to give our function two arguments: a string which accepts the format to return the time and date in, as well as the target timezone to convert to. Without further ado, let us slowly lower our function declaration into its rightful place: php Code:
Now it is time to begin filling in our function with lots of juicy bits of code. I'm assuming here that most people will want to feed in the timezone abbreviation, as that's what most people are familiar with. For example, if I lived in the UK, which luckily for this example I do, then I live in two different timezones at two different times in the year, in summer I live in BST and in winter I live in GMT. Whereas if I was presented with a list of timezones in the format: location/city, then I'd be frantically there looking for Nottingham. However, as there is no Nottingham, but rather a London, then it'd take me a little longer to realise that, and so listing it as GMT and BST, would be much easier, and also make the list a lot smaller because many cities share the same timezones. Using a function called timezone_name_from_abbr will obtain the timezone name from the abbreviation. So:Quote:
php Code:
Once we have the correct timezone name we can now call the DateTimeZone class, and subsequently the DateTime class, to get the timezone and the time as a DateTime object:php Code:
The date_default_timezone_get function as seen here uses a series of faive guesses to determine the default timezone. All that we are doing here is getting the timezone that the server we're using is currently in, and then calculating the date.Next we are going to use a try...catch statement to see if you have supplied the function with a valid timezone. The DateTimeZone construct is already configured to throw an exception if the timezone is invalid, and so what we will be doing is catching it and returning false:php Code:
Naturally, if we wanted to, we could have it echo out a message by adding the following code before return false:php Code:
This would provide us with the following message if we handed the function an invalid timezone: Quote:
php Code:
We are calling the getOffset function on our $pTargetTimezone object which has the $pLocalDate as its argument. This will allow the function to crack open the $pLocalDate object and compare it with the date in $pTargetTimezone. Seem confusing? It isn't really. As the DateTimeZone class goes about things the proper way, in pure OOP, it returns objects which are then fed into the functions.The offset in the above line is returned as an amount in seconds. Let's write the following pseudo code to help you understand:
You see how simple that is? That it is all our function does. All that's left to do now is to use that offset to modify the time and return it to the front-end. We will be using the strtotime function for this to save on over-complex functions that may end up confusing you further:This takes the time and date format you passed into the function from the function call, and then calculates the unix timestamp from the amount of offset seconds. It is then returned. As we have used the try and catch statement in our code, we will want to check if the function has returned false, and if so, inform the user that they have supplied an invalid timezone. As I am based in the GMT timezone, I will be converting the time to CST. Our function call looks like this: php Code:
We are catching the return from the function, whether that be the time and date or false. We then use the ternary operator to echo out either the date or a message depending on the value of $szDateTime. If $szDateTime contains a time and date then echo out the time and date, otherwise inform the end-user that they have supplied an invalid timezone.The time in the CST timezone, according to our script, is now: Quote:
Incidentally, I have attached the script so you can have a good and proper look at how it's done in all its glory! |
Do not that some functions used in Wildhoney's script will only work with PHP 5 >= 5.1.0.
|
hello
im a relitive noob when it comes to php but im learning. i love this script ive been looking HARD for something like this for a long time. i changed the above script to pull the "TIMEZONE" out of my database and that works fine. the problem i have is that if i use this script to enter the date of say a comment being posted by someone in GMT at 22:52 on the 10th, if its viewed right away by someone in NZDT (GMT +12) it displays the time of 22:52 on the 10th. where as i think it should be 10:52 on the 11th (NZDT) as those dates/times are the same time relitively speaking. i believe i need to store the date/time in the database in a set standard say UTC? so that when i run this script it pulls a standard date/time that it can change it as needed for the timezones. what code would i need to change to make it read a date/time field in the database and then perform the needed changes? i hope i explained everything properly. thanks for any help |
| All times are GMT. The time now is 08:44 PM. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0