【问题标题】:Send JSON date to a PHP backend, timezone is lost将 JSON 日期发送到 PHP 后端,时区丢失
【发布时间】:2016-07-03 16:47:46
【问题描述】:

我在这里遗漏了一些关于日期的内容。

假设我有一个非常基本的输入页面,像这样

标记

<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。

tl;dr

不应该是下面的代码

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

解决为 2016-03-23 UTC+1 ?

【问题讨论】:

  • 两天差?

标签: javascript php angularjs json timezone


【解决方案1】:

您的代码运行正常,但可能与您的预期不同。

您的 Javascript 日期是在浏览器中生成的,我假设时区已经设置为 Europe/Rome。如果您使用 datepicker 插件,如果您选择 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"
}

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

【讨论】:

  • 浏览器时区设置为罗马,但是当 Angular 发布日期时会出现问题,该日期被转换为 JSON 表示法 - 具有零偏移量的 iso 格式。所以客户端一切似乎都到位。但是,您的示例与我的示例相同。见这里:sandbox.onlinephpfunctions.com/code/…
  • 就像我想的那样,Z 正在抛弃解析器。我会更新我的答案。
  • 我明白你的意思,但我真的很想处理标准的 json 格式,而不需要在服务器端编码太多的自定义内容(即每个控制器操作之前的输入解析器)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 2012-04-03
  • 1970-01-01
  • 2023-03-26
  • 2012-08-12
相关资源
最近更新 更多