【问题标题】:Correctly format times between client (javascript) and the server (PHP)正确格式化客户端 (javascript) 和服务器 (PHP) 之间的时间
【发布时间】:2014-09-04 15:28:27
【问题描述】:

我在 javascript 中有一个日期对象,如下所示:

var date = 2014-12-01T00:00:00.000Z

如果我这样做:

var date = new Date(date);
date.setUTCMonth(date.getUTCMonth()+1);

然后toISOString()方法显示期望值:

2015-01-01T00:00:00.000Z

但是当我通过 POST 将该日期时间字符串发送到 PHP 脚本并使用 DateTime 类将其解析回日期时,我得到了:

2014-12-31 19:00:00 -0500

我尝试使用 DateTimeZone 类设置时区,并将时区设置为我自己的和 UTC 却没有运气:

new DateTime($_POST['DateTime'],new DateTimeZone('America/Mexico_City'));
new DateTime($_POST['DateTime'],new DateTimeZone('UTC'));

有没有办法使用Date 类在javascript 中设置时区?还有其他方法可以解决这个问题吗?我在处理时区方面的经验即使不是零也很少。

更新

这是我按照toISOString() 方法 (javascript) 的 ISO 格式时间字符串:

2014-09-01T00:00:00.000Z

这是我的$_POST var 的内容,根据print_r()

Array (
    [DateTime] => 2014-09-01T00:00:00.000Z
)

这是我的格式化程序函数的输出,使用 '%c' 格式(es_MX 语言环境):

dom 31 前 2014 年 19:00:00 CDT

以及上面提到的格式化函数:

function formatDate($date) {
    return utf8_encode(strftime('%c', $date->getTimestamp()));
}

【问题讨论】:

    标签: javascript php date datetime


    【解决方案1】:

    我认为当您发送日期字符串时,它的格式会有所不同。至少当我对此进行测试时,它可以按预期工作:

    $a = new DateTime('2015-01-01T00:00:00.000Z');
    echo $a->format('Y-m-d H:i:s'); // 输出'2015-01-01 00:00:00'

    Demo here.

    【讨论】:

      【解决方案2】:

      您遇到的问题是,当您使用以下格式时

      $date = '2015-01-01T00:00:00.000Z'; 
      

      您正在指定时区。

      注意日期末尾的“Z”,使用它相当于“nautical timezone (GMT)

      因此,当您尝试运行此代码时,您将得到完全相同的日期,即使您已将 DateTimeZone 指定为构造函数参数,这也不是您所期望的。

      $dateTime = new DateTime($date, new DateTimeZone('America/Mexico_City')); 
      echo $dateTime->format('c'). "\n"; // 2015-01-01T00:00:00+00:00
      
      $dateTime = new DateTime($date, new DateTimeZone('UTC')); 
      echo $dateTime->format('c'). "\n"; //2015-01-01T00:00:00+00:00
      

      这是预期的 PHP 行为,记录在 $timezone 参数下的 DateTime::__construct documentation 中:

      注意:

      $timezone 参数和当前时区在 $time 参数要么是 UNIX 时间戳(例如 @946684800)要么 指定时区(例如 2010-01-28T15:00:00+02:00)。

      在您的情况下,您直接在日期中指定时区(“Z”),这就是忽略 DateTimeZone 对象的原因。

      为避免这种情况并设置自定义时区,请将其设置在日期时间字符串中或去掉 Z。:

      $date = '2015-01-01T00:00:00.000';
      $dateTime = new DateTime($date, new DateTimeZone('America/Mexico_City'));
      echo $dateTime->format('c'). "\n"; // 2015-01-01T00:00:00-06:00
      
      $dateTime = new DateTime($date, new DateTimeZone('UTC')); 
      echo $dateTime->format('c'). "\n"; // 2015-01-01T00:00:00+00:00
      
      $date = '2015-01-01T00:00:00.000 America/Mexico_City';
      $dateTime = new DateTime($date);
      echo $dateTime->format('c'). "\n"; //2015-01-01T00:00:00-06:00
      

      在此处查看适用于不同版本 PHP 的代码:Demo

      还可以看看我最近问的这个相关问题:PHP DateTime Timezones - Constructor vs Setter method

      【讨论】:

      • 问题不是我得到的是 Z 区时间,而是 -0500 时间,我想要一个 Z 区时间。
      • 你能具体说明你从$_POST['DateTime']得到什么吗?
      • 还可以查看此处提供的代码中的输出:3v4l.org/0dTRW。如果您没有返回时区,您应该只在构造函数中使用new DateTimeZone('UTC'),而不是使用DateTime::setTimezone() 方法,因为您会得到不同的结果,请参阅:3v4l.org/8Zd1Y。在构造函数中它只会更改时区,在方法中它将更改时间(h:m)和时区以表示不同时区中的对象当前日期时间。查看相关问题:stackoverflow.com/questions/25658539/…
      • 与我的 JavaScript 算法中 toISOString() 方法返回的字符串完全相同,即 '2015-01-01T00:00:00.000Z'
      • 对,但是一旦你提交了你的请求并且PHP服务器处理了这个请求,那么$_POST['DateTime']中的值的内容是什么?如果您使用相同的字符串“2015-01-01T00:00:00.000Z”并将构造函数中的时区设置为 UTC,那么您将获得日期“2014-12-31 19:00:00”是没有意义的-0500",时间偏移为 -5;您不能使用正确的值,或者您正在使用DateTime::setTimezone 设置时区。如果您查看以下 Demo 3v4l.org/YStcm,您将看到 PHP 5.2.0 - 5.6.0 的所有版本的功能都是相同的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2018-09-14
      • 2023-03-12
      相关资源
      最近更新 更多