将 JSON 日期发送到 PHP 后端,时区丢失


Send JSON date to a PHP backend, timezone is lost

我在这里缺少一些关于日期的信息。

假设我有一个非常基本的输入页面,如下所示

标记

<input type="date" ng-model="item.date">
<button ng-click="test(item)">Test</button>

角度模块

angular.module('test', []).controller('ctrl', function($scope, $http){
  $scope.test = function(item) {
    $http.post('___', item);
  }
});

然后在服务器端有这个琐碎的代码。

date_default_timezone_set ( 'Europe/Rome' );
var_dump( new 'DateTime($input['date']) );

$input['date']发布 JSON 日期值,该值包含一些 ISO 格式,如下所示:

2016-03-22T23:00:00.000Z

现在,设置了时区,我希望上述ISO日期能够使用正确的时区正确处理,但我看到的是这个

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2016-03-22 23:00:00.000000"
  ["timezone_type"]=>
  int(2)
  ["timezone"]=>
  string(1) "Z"
}

应该改为解决 2016-03-23 UTC+1。

博士

不应该以下代码

date_default_timezone_set ( 'Europe/Rome' );
var_dump( new 'DateTime('2016-03-22T23:00:00.000Z');

解析至 2016-03-23 UTC+1 ?

您的代码工作正常,但可能不符合您的预期。

您的 Javascript 日期是在浏览器中生成的,我假设时区已经设置为 Europe/Rome。如果您使用日期选择器插件,如果您选择2016-03-24,您很可能会获得引用日期,这将由您的浏览器转换为本地时区。它存储的变量本身不携带有关时区的任何信息,日期字符串的Z部分只是假定它是 UTC。

在服务器上,您只需使用此日期字符串初始化日期,Z用作时区。据我所知,这不是有效的时区代码,因此假定为 UTC。

您必须在 DateTime 构造函数中显式声明要用于日期的时区,例如

$date = new DateTime($input['date'], new DateTimeZone('Europe/Rome'));

您还必须删除日期的"Z"部分。

我整理了一些东西来说明你的问题:http://sandbox.onlinephpfunctions.com/code/a545a7a87e3ad0f2e6eae1d134147aff30aec29f

<?php
//date_default_timezone_set ( 'Europe/Rome' );
$date = new 'DateTime("2016-03-23T23:00:00.000", new DateTimeZone('UTC') );
var_dump( $date ); // 2016-03-23 23:00:00.000000
$timezone = new DateTimeZone('Europe/Rome');
$date->setTimezone($timezone); 
var_dump(  $date ); // 2016-03-24 00:00:00.000000


编辑:

在 HTML 中使用以下代码尝试:

<input type="date" ng-model="item.date" ng-model-options="{timezone: 'UTC'}">

然后,您的日期将以 2016-03-18T00:00:00.000Z 的形式,您可以按原样将其发送到服务器。

在服务器上,如果你像这样解析它,就像这样

$date = new 'DateTime("2016-03-18T00:00:00.000Z" );
var_dump( $date );

这将输出

object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "2016-03-18 00:00:00.000000"
  ["timezone_type"]=>
  int(2)
  ["timezone"]=>
  string(1) "Z"
}

这可能会更接近您最初想要做的事情。