1

I am working on a PHP project that deal with time and dates and user timezones.

It needs to be accurate so I am storing the DateTime and a Timestamp in the DB as UTC time.

On the UI/Frontend I am trying to display the DateTimes based on a User's TimeZone.

I made this quick little demo Class below to demonstrate my current problem.

The createTimeCard() method should create a DateTime in UTC time and that seems to be working just fine.

The get12HourDateTime($date, $format = 'Y-m-d h:i:s a') method is used to display a DateTime to a user in there own Time Zone and also in 12 hour format time. Unfortunately this is where my problems begin. No matter what Time zone is set here, it always returns UTC time!

Can anyone help me figure out what I am doing wrong?

<?php

class TimeTest{

    public $dateTime;
    public $dateFormat = 'Y-m-d H:i:s';
    public $timeZone;

    public function __construct()
    {
        $this->timeZone = new DateTimeZone('UTC');
        $this->dateTime = new DateTime(null, $this->timeZone);
    }

    // Create a new time card record when a User Clocks In
    public function createTimeCard()
    {

        $dateTime = $this->dateTime;
        $dateFormat = $this->dateFormat;

        // Create both Timecard and timecard record tables in a Transaction
        $record = array(
            'clock_in_datetime' => $dateTime->format($dateFormat),
            'clock_in_timestamp' => $dateTime->getTimestamp()
        );

        return $record;
    }




    // Get 12 hour time format for a DateTime string
    // Simulates getting a DateTime with a USER's TimeZone'
    public function get12HourDateTime($date, $format = 'Y-m-d h:i:s a')
    {
        $timeZone = new DateTimeZone('America/Chicago');
        $date = new DateTime($date, $timeZone);

        // Also tried this with no luck
        $date->setTimezone(new DateTimeZone('America/Chicago'));

        return $date->format($format) ;
    }



}


$timeCard = new TimeTest;

$records = $timeCard->createTimeCard();

echo '<pre>';
print_r($records);
echo '</pre>';

echo $timeCard->get12HourDateTime($records['clock_in_datetime'], 'Y-m-d h:i:s a');

?>

OUTPUT

Array
(
    [clock_in_datetime] => 2013-09-21 19:28:01
    [clock_in_timestamp] => 1379791681
)

//This is in 12 hour format but is not in the new time zone!
2013-09-21 07:28:01 pm
4

2 回答 2

2

DateTime says:

Note The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).

Is this the case?

Maybe try, setTimezone():

public function get12HourDateTime($date, $format = 'Y-m-d h:i:s a')
{
    $date = new DateTime($date);
    $date->setTimezone(new DateTimeZone('America/Chicago'));

    return $date->format($format) ;
}

EDIT

public function get12HourDateTime($date, $format = 'Y-m-d h:i:s a')
{
    $date = new DateTime($date, new DateTimeZone('UTC'));
    $date->setTimezone(new DateTimeZone('America/Chicago'));
    return $date->format($format) ;
}

Since you first want to initialize the DateTime with the UTC timezone (since that corresponds to the $date), then shift it appropriately.

于 2013-09-21T19:33:49.413 回答
0

You called one constructor and that will every time assign timezone so, basically every new object created this construct is called first.

public function __construct()
{
    $this->timeZone = new DateTimeZone('UTC');
     $this->dateTime = new DateTime(null, $this->timeZone);
}

And when you use UNIX TIMESTAMP that will always return in the UTC time zone.

于 2013-09-21T19:39:19.503 回答