skip to Main Content

I have a PHP DateTime Object where the timezone has already been set to America/New_York.

I’d like to clone this object and and change the timezone of the clone to be UTC.

The resulting time should be the same moment, but the time of day should be adjusted for the new timezone.

Most examples I see suggest converting to and from string formats, which I’m not getting accurate results with.

2

Answers


  1. To clone a PHP DateTime object and change the timezone of the clone to UTC, you can utilize the DateTime::setTimezone method along with the DateTime::format method to create a new DateTime object.

    Here’s an example code snippet that demonstrates this:

    $originalDateTime = new DateTime('now', new DateTimeZone('America/New_York'));
    
    // Clone the original DateTime object
    $clonedDateTime = clone $originalDateTime;
    
    // Change the timezone of the cloned object to UTC
    $clonedDateTime->setTimezone(new DateTimeZone('UTC'));
    
    // Get the formatted date and time in UTC
    $utcDateTimeString = $clonedDateTime->format('Y-m-d H:i:s');
    
    echo 'Original DateTime: ' . $originalDateTime->format('Y-m-d H:i:s') . ' ' . $originalDateTime->getTimezone()->getName() . "n";
    echo 'Cloned DateTime (UTC): ' . $utcDateTimeString . ' ' . $clonedDateTime->getTimezone()->getName() . "n";
    

    In the above code, we first create the original DateTime object with the timezone set to ‘America/New_York’. Then, we clone the original DateTime object using the clone keyword to create a new object with the same date and time values. Next, we change the timezone of the cloned object to ‘UTC’ using the setTimezone method. Finally, we retrieve the formatted date and time in the UTC timezone using the format method.

    The output will display the original DateTime in the ‘America/New_York’ timezone and the cloned DateTime in the ‘UTC’ timezone.

    Note: It’s important to use the clone keyword when creating the clone of the DateTime object to ensure that the original object remains unaffected.

    Login or Signup to reply.
  2. Most of the time in PHP, you are better off using DateTimeImmutable objects, which work the same as DateTime objects, but all their methods return a new object, rather than changing the existing one.

    With that, there is a method to do exactly what you want: DateTimeImmutable::setTimezone. Adapting the example from that manual page (see live demo):

    $newYorkDateTime = new DateTimeImmutable('2023-06-09 09:30', new DateTimeZone('America/New_York'));
    
    $utcDateTime = $newYorkDateTime->setTimezone(new DateTimeZone('UTC'));
    
    echo $newYorkDateTime->format('Y-m-d H:i:sP') . "n";
    echo $utcDateTime->format('Y-m-d H:i:sP') . "n";
    

    If you really need to work with mutable DateTime objects, you will need to clone the object first, then modify the clone, to avoid it being modified in place (live demo):

    $newYorkDateTime = new DateTime('2023-06-09 09:30', new DateTimeZone('America/New_York'));
    
    $utcDateTime = clone $newYorkDateTime;
    $utcDateTime->setTimezone(new DateTimeZone('UTC'));
    
    echo $newYorkDateTime->format('Y-m-d H:i:sP') . "n";
    echo $utcDateTime->format('Y-m-d H:i:sP') . "n";
    

    If you are given a DateTime object by some other code, and want to use DateTimeImmutable in your own code, you can use DateTimeImmutable::createFromMutable or (since PHP 8.0) DateTimeImmutable::createFromInterface (which accepts either DateTime or DateTimeImmutable objects), like this (live demo):

    $newYorkDateTime = new DateTime('2023-06-09 09:30', new DateTimeZone('America/New_York'));
    $newYorkDateTimeImmutable = DateTimeImmutable::createFromMutable($newYorkDateTime);
    
    $utcDateTime = $newYorkDateTimeImmutable->setTimezone(new DateTimeZone('UTC'));
    
    echo $newYorkDateTimeImmutable->format('Y-m-d H:i:sP') . "n";
    echo $utcDateTime->format('Y-m-d H:i:sP') . "n";
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search