12

I want to convert date form from d/m/Y to Y-m-d with timezone offset. I am able to convert from d/m/Y to Y-m-d with this code:

$date = DateTime::createFromFormat('d/m/Y', $date);
$date = $date->format('Y-m-d');

But I am not sure how to add the timezone offset.

yoshi
  • 1,287
  • 3
  • 15
  • 28

3 Answers3

32

(PHP 5 >= 5.3.0) you actually enter the third parameter

public static DateTime DateTime::createFromFormat(string $format , string $time[, DateTimeZone $timezone])

$date = DateTime::createFromFormat('d/m/Y', $date, new DateTimeZone('Europe/Berlin'));
denoise
  • 1,067
  • 2
  • 14
  • 40
  • 9
    I don't know why this answer is not selected as solution. This is correct answer. – ofca Jun 14 '17 at 10:01
  • 3
    It does not work for me.. It seems like third parameter (`DateTimeZone` Object) was simply ignored. The only way to achieve this was to use the validated answer published by @John Conde I am running PHP 5.6.30 – Delphine Sep 26 '17 at 16:33
  • 1
    This works as described if you set $tz to the correct timezone, but you have to do it manually. new \DateTimeZone(date_default_timezone_get()) sets the system default. – j4k3 Nov 22 '17 at 11:00
  • The 3rd parameter does absolutely bipkis. – Kafoso Apr 03 '19 at 13:17
  • @Kafoso Only if your default timezone happens to be GMT. If you're in any other timezone it's absolutely essential that you specify it. – j4k3 Oct 30 '19 at 10:01
24

Just use DateTime::setTimeZone():

$date = DateTime::createFromFormat('d/m/Y', $date);
$date->setTimeZone(new DateTimeZone('America/New_York'));
$date = $date->format('Y-m-d');
John Conde
  • 217,595
  • 99
  • 455
  • 496
  • Can I somehow use for example `+2:00` instead of `America/New_York`? I know you should use timezones and not offsets because of daylight savings etc. but on this environment timezones like `America/New_York` are not working. – yoshi Jun 17 '14 at 20:13
  • 1
    See if [this answer](http://stackoverflow.com/a/7276486/250259) does what you need – John Conde Jun 17 '14 at 20:14
  • Just to clarify. This does convert a date (user input and user's timezone) to the server timezone. So `America/New_York` is the timezone of the user? – yoshi Jun 17 '14 at 20:35
  • 11
    Note that this example first creates `$date` in the server's timezone, and then when `setTimeZone()` is called, it *converts* it to "America/New_York". In other words, it introduces a time component - `$date` is no longer at midnight. Might not be a big deal for some, but it was for me! – rinogo Jul 08 '16 at 22:53
  • Probably easiest way would be to create temp object and then new object base on temp. Like described below: $dateInServerTimeZone = DateTime::createFromFormat('d/m/Y', $dateString); $dateInWantedTimeZone = new DateTime($dateInServerTimeZone->format("Y-m-d H:i:s"), new DateTimeZone($createInZone)); Where $createInZone is a timzone name example "America/New_York" or "UTC" etc – Aivar Nov 06 '16 at 19:02
  • This will convert the given datetime to the new timezone, but this is not the same as creating the given date within the timezone to begin with. This answer will result in the digits changing, as it is representing the same datetime within a different timezone. Alternatively, specifying the timezone as a parameter in \DateTime::createFromFormat will not change the digits, because the datetime will be created within that timezone to begin with. Which answer is better depends on whether you want to convert to timezone or create in timezone. – kloddant Jan 23 '23 at 16:09
0

I tested both the solutions JohnConde and denoise.

with this script:

$format = 'Y-m-d H:i:s';
$datetime_str = '2022-10-28 17:24:00';
$timezone_str = 'Europe/Rome';

$dt_test_denoise = DateTime::createFromFormat($format, $datetime_str, 
                                         new DateTimeZone($timezone_str));
echo '$dt_test_denoise:';
echo "<br/>";
var_dump($dt_test_denoise);
echo "<br/>";
echo "<br/>";

$dt_test_JohnConde = DateTime::createFromFormat($format, $datetime_str);
$dt_test_JohnConde->setTimeZone(new DateTimeZone($timezone_str));
echo '$dt_test_JohnConde:';
echo "<br/>";
var_dump($dt_test_JohnConde);
echo "<br/>";
echo "<br/>";

execute this on http://phptester.net/ and you will see the differences.

I think the best is solution denoise!