简体   繁体   中英

PHP date time zone conversion - days

I have date conversion issue: The goal is to determine an "order by date" for a book, this should be 13 days prior to the book's "release date", which is in EST. The "order by date" should display the 13 day time frame plus any time diff between the user's time and EST (New York) time. So in my function below, I'm getting the release date, NYC time, user's time and trying to do order_by_date = release_date - ( (nyc/user local time diff) + 13 days). It seemed to be working, but after testing this out with multiple release dates, I'm consistently returning a 14 day difference, not a 13 day one... My main question is why would the function below output a date that is 14 days before a release date and not 13 days? I've tried echoing each time variable and each one looks normal (ie for a user in NYC, the time diff is 0, but for someone on PST it's 3hour diff), I wonder if the formatting is having an effect on the value? Thanks for any input:

function get_order_by_date( ) {
        $release_date = '26-02-2019 00:00:00'
        $ny_timezone = new \DateTimeZone( 'America/New_York' );
        $gmt_timezone = new \DateTimeZone( 'GMT' );
        $user_date_time = new \DateTime( $release_date, $gmt_timezone );
        $offset = $ny_timezone->getOffset( $user_date_time );
        $my_interval = \DateInterval::createFromDateString( (string) $offset . 'seconds' );
        $user_date_time->add( $my_interval );
        $result = $user_date_time->format( 'd-m-Y H:i:s' );
        $order_by_date = date( 'F jS', strtotime( $result . ' - 13 days' ) );

        return $order_by_date;
    }

It might be easier to see why we get a certain date as a result if we simplify the process a little. If I understand correctly the function needs to take the release date and do two things to it:

  1. Shift 13 days prior to it
  2. Set it to the user's timezone

If we start with the release date in the release timezone, making those modifications is more straightforward.

For the purposes of the answer I'm returning the result in a format that includes the time so we can see exactly where those modifications put the result, but you can use whatever format is needed.

<?php

function get_order_by_date(string $release_date, string $user_timezone)
{
    $release_timezone = new \DateTimeZone( 'America/New_York' );
    $user_timezone = new \DateTimeZone($user_timezone);

    // start with the release date in NY time
    $orderby_date = new \DateTime($release_date, $release_timezone);

    // 13 days prior
    $orderby_date->modify('-13 days');

    // shift to the user's timezone
    $orderby_date->setTimezone($user_timezone);

    return $orderby_date->format('Y-m-d H:i:s');
}

Using the date in your example, 26-02-2019 00:00:00 moving thirteen days before would give you 13-02-2019 00:00:00 .

At that time in NY, the time in LA would be three hours earlier, so the result would be in the previous day

echo get_order_by_date('26-02-2019 00:00:00', 'America/Los_Angeles');  // 2019-02-12 21:00:00

And the time in GMT would be five hours later, so the result would be in the same day

echo get_order_by_date('26-02-2019 00:00:00', 'GMT');  // 2019-02-13 05:00:00

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM