PHP DateTime and DateTimeZone Tutorial

Written by on June 3, 2008 in Must Reads, PHP - 23 Comments

With each new version PHP is getting more and more object oriented. In version 5.x we get two useful classes for date and time handling. Many programmers are still using outdated methods which are available in PHP mainly for compatibility reasons, so i want to introduce you to DateTime and DateTimeZone objects.

Server default Timezone

Before i do that, first let’s start with some basics, which tend to cause a lot of troubles in the beginning. Each computer has it’s own default timezone and local time set. If you are using Microsoft Windows, then probably timezone on your local machine is already set correctly, on the other hand if you are using Linux chances are that you will have to do it manually (i had to, however i am not using typical Linux so maybe this is just me).

PHP default Timezone

More over PHP has also it’s own default timezone, but doesn’t have it’s own time, which would be completely redicolous anyway. Obviously default PHP timezone can be found and changed in php.ini file, look for similar lines:

[Date]
; Defines the default timezone used by the date functions
date.timezone = 'Europe/Warsaw'

I set date.timezone to Europe/Warsaw because it is my timezone, besides i have the same timezone set on my local machine. If you also changed these setting remember to restart your server before procceding.

Ok, enough with theory, when you run your scripts you can check and change your script timezone anytime you want. What does “script timezone” mean? Simply, that, despite you overwrite value from php.ini settings, this change is visible only in script which made this change.

It may sound complicated, but it is not and everything is done with only two functions, date_default_timezone_get() – which reads default timezone used in script, date_default_timezone_set() – sets default script timezone:

echo date_default_timezone_get();
echo date('H:i:s');
date_default_timezone_set('GMT');
echo date_default_timezone_get();
echo date('H:i:s');

This script in my case outputs:

Europe/Berlin
21:32:46
GMT
19:32:46

To be honest i have no idea why my default timezone is Europe/Berlin while i set it to Europe/Warsaw, more over phpinfo() says that my timezone is Europe/Warsaw, however there is no time difference between Berlin and Warsaw so everything is somewhat ok. Notice that when we changed default timezone, date or rather time has changed also.

DateTime and DateTimeZone

It often happens (or it just happened lately to me) that we want to know what is the time in different part of the world, this can be easily done using mentioned earlier DateTime and DateTimeZone classes.

$dateTime = new DateTime("now", new DateTimeZone('Europe/Warsaw'));
echo $dateTime->format("Y-m-d H:i:s");
 
$dateTimeZone = new DateTimeZone('GMT');
$dateTime->setTimezone($dateTimeZone);
 
echo $dateTime->format("Y-m-d H:i:s");

The Output:

2008-06-02 21:32:46
2008-06-02 19:32:46

I know it’s a bit late, but i will finish this post anyway :) . In the first line we create an instance of DateTime class, first argument passed to the constructor is time, i passed “now” which has the same meaning as NOW() in SQL. Second argument has to be instance of DateTimeZone class. You can also do not pass any arguments at all, then defaults will be used.

Take a look at fourth line, we simply change $dateTime timezone with DateTime::setTimezone() and voila, conversion from one timezone to another is done. As you can see conversion between two different timezones is very easy with these two classes.

Calculating difference between two dates

Did you ever wanted to calculated difference in days between two dates? Without DateTime class it could be quite diffycult, but isn;t anymore:

function dateDiff($dt1, $dt2, $timeZone = 'GMT')
{
    $tZone = new DateTimeZone($timeZone);
    $dt1 = new DateTime($dt1, $tZone);
    $dt2 = new DateTime($dt2, $tZone);
 
    $ts1 = $dt1->format('Y-m-d');
    $ts2 = $dt2->format('Y-m-d');
 
    $diff = abs(strtotime($ts1)-strtotime($ts2));
 
    $diff/= 3600*24;
 
    return $diff;
}
 
echo dateDiff('2008-01-05', '2008-05-20');

The only new (but not quit new in PHP) function here is strtotime() which parses date wrote as as string to UNIX timestamp. After substracting two timestamps, $diff is equal to number of seconds between these two days, we wanted to have difference in days, so we need to make additional arithmetic operations and return result. The most important here is use of the same timezone, if you forget about it then number of days may not be integer but real.

Other usage

I think you have to agree that DateTime and DateTimeZone classes are very useful however it is a schame that programmers didn’t thaught it would be handy to add __toString() method to both of this classes, but we are programmers as well so there is no problem in exending base classes:

class DTime extends DateTime
{
    public static $Format = 'Y-m-d H:i;s';
 
    public function __construct($date = null, DateTimeZone $dtz = null)
    {
        if($dtz === null)
        {
            $dtz = new DateTimeZone(date_default_timezone_get());
        }
        parent::__construct($date, $dtz);
    }
 
    public function __toString()
    {
        return (string)parent::format(self::$Format);
    }
}
$dTime = new DTime();
echo $dTime;

Outputs: 2008-06-02 19:32-46

Last thing i want to talk about is modyfing timestamp:

$date = new DateTime("2006-12-12");
$date->modify("+1 day");
echo $date->format("Y-m-d"); // 2006-12-13

This example was taken directly from PHP documentation, when you check date_modify() documentation you will find many more examples there, i won’t list them here becuase it simply doesn’t make any sense.

About the Author

Greg Winiarski is a freelance PHP and JavaScript programmer. He specializes in web applications and WordPress development.

23 Comments on "PHP DateTime and DateTimeZone Tutorial"

  1. shoping carts July 15, 2008 at 7:38 am ·

    Thanks,
    That’s nice post.
    It has helped me fixing my problem related to handling of date and time in PHP.

  2. ghprod September 16, 2008 at 12:23 am ·

    Finally , i’ve got this tutorial :)

    Thnx … i just need this to count automatic PHP day by day :)

  3. Arden Harper September 23, 2008 at 4:52 pm ·

    Ah! Many thanks for this – I’ve been struggling with this all week

  4. Mark November 8, 2008 at 5:27 pm ·

    For those who use php classes, a tip is to try the “__autoload” function as a replacement for many includes or requires. I use it this way:

    function __autoload($class_name) {
        require_once($DOCUMENT_ROOT. "classes/class.". $class_name. ".php");
    }

    Then when my php routine tries to create a new instance of that class like this: $newinstance = new phpMyClassHere;

    the class will be found and included automatically from my “../classes/” directory. Note the file name must match the class name in this example, or you change __autoload as I did above. In the above example, my fictitious file
    name would be “class.phpMyClassHere.php” …

    See the php documentation for more information:
    http://us.php.net/__autoload

    Try this and see if it helps!
    Mark, ajamyajax.com

  5. Greg November 11, 2008 at 12:44 pm ·

    Well Mark, another great tip from you :)

    Although i think this topic deserves a separate article, because it will be hard to find thru search engines (and this is where most of us look for help :) ), those who will find this article usually are interested only in DateTime functions and rarely make it to the comments.

    Anyway you explained it very well, so i would like to use your code and maybe some text in the post about __autoload if you don’t mind?

  6. Mark November 11, 2008 at 4:52 pm ·

    Hi Greg. Sure, anything you want to do with this tip is fine with me. Sorry to put this here, was just a quick idea and post… If you move it, maybe you could fix my extra post to make this easier for people to read, putting the function back up in the help text? Or re-writing it your own way is fine also! Have a good one.

  7. Greg November 13, 2008 at 6:49 pm ·

    Hi Mark, i merged your two posts into one and added syntax highlighting, it looks good to me.

    Also, like i said i wrote new post about _autoload function with affiliation to your comment.

  8. dave March 9, 2009 at 3:16 pm ·

    thanks for the post sir Greg great post

  9. 王富明 March 24, 2009 at 5:07 am ·

    Thanks!!!

  10. RvW June 8, 2009 at 10:36 pm ·

    Hii
    tings like $date = new DateTime(’next Thursday’);
    are possible you where i can find al commands ?

  11. EastGhostCom December 23, 2009 at 6:48 pm ·

    IMPORTANT: Look into spl_autoload_register() which lets you manage a stack of several __autoload() functions.

    Also, the require_once() is costly, VERY costly, even with APC. The guy who initially wrote this thought stream unfortunately (and erroneously) wrote require_once() instead of the far faster include(). Since PHP only calls __autoload() when it can not find in memory the class, there is absolutely zero (and in fact negative) sense in using require_once() when include() works just as well and is far faster to boot.

  12. cocopeat January 23, 2010 at 4:58 pm ·

    very usefull! Thx

  13. slow internet new york March 28, 2010 at 4:49 am ·

    I am glad to find out that there is still a little terrific content left on the internet. I have gotten so fed up with google giving me junk.

  14. chen May 25, 2010 at 6:00 am ·

    This is what i need! Thanks!

  15. shaffy August 2, 2010 at 11:50 am ·

    Thanks,
    That’s nice post.

  16. Pradeep August 18, 2010 at 6:22 pm ·

    I am struggling to run this simple code,
    getLocation());
    ?>

    Error:
    PHP Fatal error: Call to undefined method DateTimeZone::getLocation()

    Do I need to install something?
    I am running it at local m/c

  17. Folding Cycles September 10, 2010 at 2:22 am ·

    I have long been attempting to explain the exact same thing to my friends but I think it’s better if I simply email them the link to this article instead. Thankyou for writing such an easy to read informative post.Hey how’s it going?

  18. Sam September 30, 2010 at 7:24 am ·

    Thank you, I really helpedd me.

  19. Jack October 4, 2010 at 6:24 pm ·

    Greetings, Interesting post. I’ve only found out about the blogosphere within the last couple of weeks and I am completely addicted!! It is sites like this that are responsible! :) I have been so inspired that I decided to make my own site. I’m in the middle of researching for an article i am writing and was wondering if I may link to your post? I think it will be of great interest to my readers. Cheers! Keep up the good work. Jack

  20. thaale la la laa la December 15, 2010 at 2:07 pm ·

    ya this is really good but not work but output is good actually its does not work properly but its better than

  21. Erik June 7, 2011 at 11:02 pm ·

    Pretty useful. But you might wanna do minor spell checking of your posts:

    redicolous –> ridiculous
    possessive “it’s” (3 times) –> its

  22. Health Product August 3, 2011 at 2:51 pm ·

    Hi, Nice tutorial. What if i want the sql time formatted into php code.

    Like, i added an item to my blog and i want to see that when I have added that item of I’ll check that particular item after 2-3 hrs. and it says: This item was added 10 sec ago, or 40 minutes ago or 2 hrs. ago etc.

    how do i get that time delay variables? please explain or email the code to me as I needed it.

    thank you.

  23. tft August 12, 2011 at 9:12 am ·

    Thankx.It really helped me.

Leave a Comment