105

So I've checked the list of supported time zones in PHP and I was wondering how could I include them in the date() function? Thanks!

I don't want a default timezone, each user has their timezone stored in the database, I take that timezone of the user and use it. How? I know how to take it from the database, not how to use it, though.

Kerem
  • 11,377
  • 5
  • 59
  • 58
user2917204
  • 1,243
  • 2
  • 9
  • 11

16 Answers16

180

For such task, you should really be using PHP's DateTime class. Please ignore all of the answers advising you to use date() or date_set_time_zone, it's simply bad and outdated.

I'll use pseudocode to demonstrate, so try to adjust the code to suit your needs.

Assuming that variable $tz contains string name of a valid time zone and variable $timestamp contains the timestamp you wish to format according to time zone, the code would look like this:

$tz = 'Europe/London';
$timestamp = time();
$dt = new DateTime("now", new DateTimeZone($tz)); //first argument "must" be a string
$dt->setTimestamp($timestamp); //adjust the object to correct timestamp
echo $dt->format('d.m.Y, H:i:s');

DateTime class is powerful, and to grasp all of its capabilities - you should devote some of your time reading about it at php.net. To answer your question fully - yes, you can adjust the time zone parameter dynamically (on each iteration while reading from db, you can create a new DateTimeZone() object).

Alex
  • 5,510
  • 8
  • 35
  • 54
N.B.
  • 13,688
  • 3
  • 45
  • 55
  • 1
    @Glavić - you are correct, I'll leave the answer in to show how _not_ to do this. However, DateTime beats manipulating server's timezone, which is what I wanted (but failed) to point out. – N.B. Nov 30 '13 at 21:09
  • you code does not work as the first parameter for the DateTime constructor must be a string [ http://php.net/manual/en/datetime.construct.php ] – Alex Apr 03 '15 at 08:43
  • @Alex - Yep, it's incorrect - which is what I commented about and left the answer in. I'll edit the answer to include the correct constructor when I un-lazy myself :) (in the mean time, you might edit the answer too?) – N.B. Apr 03 '15 at 09:15
  • 2
    Why do you set the timestamp to the timestamp now, since you already initiated the DateTime with 'now' ? – George Dimitriadis May 01 '17 at 09:29
  • @GeorgeDimitriadis because it's an example of how to use the code. It serves the purpose of highlighting what you *can* do. You are correct in stating that it's basically pointless in *this* instance, but I put it there so people can see how a timestamp can be altered on a created `DateTime` object. – N.B. May 26 '17 at 10:02
  • The DateTime() class as used in this example is untenably slooooooow. Had to debug why my page load times increased 200x fold, and it turned out it was due to this nasty bugger! – Thoracius Appotite Jul 12 '18 at 01:18
  • 1
    @ThoraciusAppotite random comments without code and facts mean nothing. If you don't have any code to shows this 200x slowdown, I'm inclined not to believe you. – N.B. Jul 12 '18 at 06:55
  • I mistyped. it's a 20x slowdown. – Thoracius Appotite Jul 13 '18 at 16:47
  • 1
    @ThoraciusAppotite and still no code. Or any notion of what you're doing. Or how you measured the performance. If that really is the case, it'd be great if you shared your findings so the rest of us can replicate it. However, you took the time to reply twice yet you didn't post a single line of code. I think you can understand why your comment looks like bs. – N.B. Jul 13 '18 at 23:00
  • I can't post code in a comment, there's not enough room. I time my script with microtime(True). Try it for yourself – Thoracius Appotite Jul 14 '18 at 05:00
  • @ThoraciusAppotite https://3v4l.org/0WDe7/perf#output looks pretty good to me. Unless you are running this in a massive loop. – Richard A Quadling Jun 29 '20 at 11:17
48

If I understood correct,You need to set time zone first like:

date_default_timezone_set('UTC');

And than you can use date function:

// Prints something like: Monday 8th of August 2005 03:12:46 PM
echo date('l jS \of F Y h:i:s A');
COil
  • 7,201
  • 2
  • 50
  • 98
Suresh Kamrushi
  • 15,627
  • 13
  • 75
  • 90
  • 2
    I don't want a default timezone, it'll be stored in a database for every user. – user2917204 Nov 29 '13 at 15:18
  • 3
    @user2917204 If you're using MySQL, store as a `TIMESTAMP` data type. Those store in UTC on the backend so they can be converted to any timezone of your choosing. – ceejayoz Nov 29 '13 at 15:19
  • I'm using MySQL and I have it stored as TIMESTAMP, what's the code that I need to have to convert it? – user2917204 Nov 29 '13 at 15:23
  • 1
    @user2917204 Create a function that sets the timezone, spits out the formatted date, and puts the timezone back. Plenty of examples http://stackoverflow.com/questions/11900126/changing-date-and-time-between-timezones, http://stackoverflow.com/questions/7824038/implementing-internationalization-language-strings-in-a-php-application/7906609#7906609. The DateTime class also accepts a timezone param http://php.net/manual/en/class.datetime.php – Mike B Nov 29 '13 at 15:26
20

The answer above caused me to jump through some hoops/gotchas, so just posting the cleaner code that worked for me:

$dt = new DateTime();
$dt->setTimezone(new DateTimeZone('America/New_York'));
$dt->setTimestamp(123456789);

echo $dt->format('F j, Y @ G:i');
Andrew
  • 18,680
  • 13
  • 103
  • 118
19

Use the DateTime class instead, as it supports timezones. The DateTime equivalent of date() is DateTime::format.

An extremely helpful wrapper for DateTime is Carbon - definitely give it a look.

You'll want to store in the database as UTC and convert on the application level.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • Yes, it can. You'd handle that in your application logic, using the `setTimezone()` functions of those classes. – ceejayoz Nov 29 '13 at 15:32
12

It should like this:

date_default_timezone_set('America/New_York');
user3049608
  • 155
  • 2
  • 3
    I don't want a default timezone, each user has their timezone stored in the database, I take that timezone of the user and use it. How? I know how to take it from the database, not how to use it, though. – user2917204 Nov 29 '13 at 15:24
  • It doesn't create a default timezone for all users, just the current script, which presumably would be responding to the actions of 1 current user. – LStarky Aug 28 '17 at 02:09
  • This is essentially changing globals, which is almost never the right thing to do. Using DateTime and DateTimeZone keeps calculations local and without scary side effects. – oligofren Jan 20 '22 at 21:06
8

U can just add, timezone difference to unix timestamp. Example for Moscow (UTC+3)

echo date('d.m.Y H:i:s', time() + 3 * 60 * 60);
Mike.Stanley
  • 191
  • 2
  • 2
  • Nice. Unfortunately `date()` only accepts up to 2 parameters, so I couldn't use it in conjunction with `strtotime()` (e.g., `date('Y-m-d', time() + -6 * 60 * 60, strtotime('-1 days'))`). – velkoon Apr 25 '21 at 05:10
4

Based on other answers I built a one-liner, where I suppose you need current date time. It's easy to adjust if you need a different timestamp.

$dt = (new DateTime("now", new DateTimeZone('Europe/Rome')))->format('d-m-Y_His');
Kar.ma
  • 743
  • 6
  • 12
3

Try this. You can pass either unix timestamp, or datetime string

public static function convertToTimezone($timestamp, $fromTimezone, $toTimezone, $format='Y-m-d H:i:s') 
    {
        $datetime = is_numeric($timestamp) ?
                    DateTime::createFromFormat ('U' , $timestamp, new DateTimeZone($fromTimezone)) :
                    new DateTime($timestamp, new DateTimeZone($fromTimezone));

        $datetime->setTimezone(new DateTimeZone($toTimezone));

        return $datetime->format($format);
    }
Community
  • 1
  • 1
dzona
  • 3,323
  • 3
  • 31
  • 47
3

this works perfectly in 2019:

date('Y-m-d H:i:s',strtotime($date. ' '.$timezone)); 
emmanuel
  • 133
  • 3
2

I have created this very straightforward function, and it works like a charm:

function ts2time($timestamp,$timezone){ /* input: 1518404518,America/Los_Angeles */            
        $date = new DateTime(date("d F Y H:i:s",$timestamp));
        $date->setTimezone(new DateTimeZone($timezone));
        $rt=$date->format('M d, Y h:i:s a'); /* output: Feb 11, 2018 7:01:58 pm */
        return $rt;
    }
2

I have tried the answers based on the DateTime class. While they are working, I found a much simpler solution that makes a DateTime object timezone aware at the time of creation.

$dt = new DateTime("now", new DateTimeZone('Asia/Jakarta'));
echo $dt->format("Y-m-d H:i:s");

This returns the current local time in Jakarta, Indonesia.

1

Not mentioned above. You could also crate a DateTime object by providing a timestamp as string in the constructor with a leading @ sign.

$dt = new DateTime('@123456789');
$dt->setTimezone(new DateTimeZone('America/New_York'));
echo $dt->format('F j, Y - G:i');

See the documentation about compound formats: https://www.php.net/manual/en/datetime.formats.compound.php

Team EJ
  • 101
  • 1
  • 2
0

If you use Team EJ's answer, using T in the format string for DateTime will display a three-letter abbreviation, but you can get the long name of the timezone like this:

$date = new DateTime('2/3/2022 02:11:17');
$date->setTimezone(new DateTimeZone('America/Chicago'));

echo "\n" . $date->format('Y-m-d h:i:s T');
/* Displays 2022-02-03 02:11:17 CST "; */

$t = $date->getTimezone();
echo "\nTimezone: " . $t->getName();
/* Displays Timezone: America/Chicago */
Bob Ray
  • 1,105
  • 10
  • 20
0
$now = new DateTime();
$now->format('d-m-Y H:i:s T')

Will output:

29-12-2021 12:38:15 UTC
0

I had a weird problem on a hosting. The timezone was set correctly, when I checked it with the following code.

echo ini_get('date.timezone');

However, the time it returned was UTC.

The solution was using the following code since the timezone was set correctly in the PHP configuration.

date_default_timezone_set(ini_get('date.timezone'));
B. Martin
  • 1,047
  • 12
  • 18
-1

You can replace database value in date_default_timezone_set function, date_default_timezone_set(SOME_PHP_VARIABLE); but just needs to take care of exact values relevant to the timezones.

Yatin Trivedi
  • 661
  • 6
  • 9