使用DateTime和DateTimeZone在用户时区显示GMT不起作用

时间:2016-09-30 15:09:42

标签: php oop datetime timezone

背景

我正在尝试创建一个事件调度程序,向用户显示一天的事件。它看起来像这样。

enter image description here

在左侧,您可以看到15分钟的时间间隔,每个间隔下面是相应的unix时间戳。

问题:

以两个用户为例。

Gemma来自伦敦,格林尼治标准时间+01:00

Françoise来自巴黎,格林尼治标准时间+02:00

当Gemma查看她的活动时间表时,每15分钟一行应显示......

  • a)他们时区的时间和
  • b)相应的unix时间戳

例如,从格林威治标准时间上午10:00到上午11:00(2016-9-30)的时间段,他们会看起来像这样。

  

对于杰玛:

     
      
  • 11:00 => 1475229600(格林尼治标准时间10:00)
  •   
  • 11:15 => 1475230500(格林尼治标准时间10:15)
  •   
  • 11:30 => 1475231400(格林尼治标准时间10:30)
  •   
  • 11:45 => 1475232300(格林尼治标准时间10:45)
  •   
  • 12:00 => 1475233200(格林威治标准时间11:00)
  •   
     

对于Françoise:

     
      
  • 12:00 => 1475229600(格林尼治标准时间10:00)
  •   
  • 12:15 => 1475230500(格林尼治标准时间10:15)
  •   
  • 12:30 => 1475231400(格林尼治标准时间10:30)
  •   
  • 12:45 => 1475232300(格林尼治标准时间10:45)
  •   
  • 13:00 => 1475233200(格林威治标准时间11:00)
  •   

我的代码

以下是我生成时间段的函数

/**
 * intervals
 */
public function getTimeSlots($year, $month, $day, $start_time = '06:00', $end_time = '20:00')
{
    $date = $year . '-' . $month . '-' . $day; // 2016-9-30
    $unix_base_time = $this->getUnixTimeStamp($date); // unix timestamp for 2016-9-30 00:00

    $seconds_start = strtotime('1970-01-01 ' . $start_time . ' UTC'); // 21600 seconds
    $seconds_end   = strtotime('1970-01-01 ' . $end_time . ' UTC');   // 72000 seconds

    while ($seconds_start <= $seconds_end) {
        $slots[$unix_base_time + $seconds_start] = $this->getTime($date, '+' . $seconds_start . ' seconds');
        $seconds_start = $seconds_start + 900; // plus 15 minutes
    }
    return $slots;
}

/**
 * timestamps
 */
public function getUnixTimeStamp($offset = 'now')
{
    $date = new DateTime($offset, new DateTimeZone('UTC'));
    return $date->format('U'); // returns a unix timestamp
}


/**
 * time
 */
public function getTime($date = 'now', $offset = 'now')
{
    $date = new DateTime($date, new DateTimeZone($this->session->userdata('time_zone')));
    $date->modify($offset);
    return $date->format('H:i');
}

如果我输出var_dump,我得到以下内容:

array(57) {
  [1475215200]=>
  string(5) "06:00"
  [1475216100]=>
  string(5) "06:15"
  [1475217000]=>
  string(5) "06:30"
  [1475217900]=>
  string(5) "06:45"
  [1475218800]=>
  string(5) "07:00"
  etc......
}

unix时间戳是正确的,但时间显示为GMT而不是用户时区!

显然我在getTime()函数中做错了。

当我清楚地注入DateTimeZone对象并将用户时区作为参数传递时,我无法理解为什么它将时间('H:i')作为GMT返回。

1 个答案:

答案 0 :(得分:1)

创建新的DateTime对象时,您传入的时区将被视为传入日期的时区。在你的情况下,你告诉DateTime将秒数解释为GMT + 1,一次解释为GMT + 2.

请尝试以下方法:

// our $date is in UTC because we derived it from unix timestamps
$date = new DateTime($date,
       new DateTimeZone('UTC'));
$date->modify($offset);
// update the timezone. The time will be interpreted accordingly.
$date->setTimeZone(new DateTimeZone($this->session>userdata('time_zone')));
return $date->format('H:i');