【发布时间】:2014-05-15 20:46:03
【问题描述】:
我试图弄清楚如何从表单中接受日期/时间,因此在用户的时区中,并在将其插入数据库之前将其更改为 UTC。出于某种原因,再多的搜索也没有让我得到答案。
我的表单会将用户选择的任何日期发布到我的代码中,所以我希望能够做这样的事情。注意:$userDate 可能与基于用户位置的任意数量的时区有关
$userDate = $_POST['user_date'] // 2014-05-15 16:37:23
我预计在我的表单上使用 Date().getTimezoneOffset() 来提交用户的 UTC 偏移量 (as detailed here).
$userOffset = $_POST['user_offset']
然后在将日期插入我的数据库之前,我想将其转换为 UTC——但我很难用 PHP 来做到这一点(我实际上使用的是 Laravel,所以如果你知道使用 Carbon 的方法,这会更容易,但我在他们的文档中找不到)。
我一直很想手动解析偏移量并将其转换为秒数,然后将其添加或减去 $userDate 的 strtotime() 输出,然后使用 date() 将其转换回日期格式 - - 但必须有更好的方法!
我在这里缺少什么? PHP 是否有一个我不知道的功能,可以让我做类似的事情:
$userDate = '2014-05-15 16:37:23';
$userOffset = '+04:00';
$utcDate = date_apply_offset($userDate, $userOffset);
echo $utcDate; // Outputs: 2014-05-15 20:37:23
还是我让这件事变得更难了?
编辑
基于@vascowhite 提供的解决方案,我采用了以下方法(添加到问题中以改进寻求指导的答案)
我最终使用了来自 moment.js 的函数,因为我已经在使用它将 UTC 转换为显示的用户时区。
HTML:
<input id="user_offset" type="hidden" name="user_offset" value="">
Javascript:
var offset = moment().format('ZZ');
$('#user_offset').val(offset);
PHP(在自定义日期类中):
class MyDate {
/**
* Convert Date to UTC
*
* @param string $date Any date parsable with strtotime()
* @param string $offset UTC offset of date
*/
public static function toUTC($date, $offset = '+0:00')
{
if ($timestamp = strtotime($date) && ! empty($offset) )
{
$newDate = date('Y-m-d H:i:s', $timestamp);
$newDate = new \DateTime($date . ' ' . $offset);
$newDate->setTimezone(new DateTimeZone('UTC'));
$date = $newDate->format('Y-m-d H:i:s');
}
return $date;
}
}
// To convert
$userDate = trim($_POST['user_offset']);
$userOffset = trim($_POST['user_date']);
$utc = MyDate::toUTC($userDate, $userOffset)
该类方法并不完美,如果出现问题,它只会返回日期——实际上它应该抛出异常。
【问题讨论】:
-
你看过mktime吗? php.net/manual/en/function.mktime.php
-
为什么不从前端本身获取 UTC 时间戳?如果使用 JS,你可以使用 Math.floor((new Date()).getTime() / 1000)
-
确保当您致电
getTimezoneOffset时,您是根据在表单中输入的日期进行的。当前偏移量不一定与该时间点的偏移量相同!另请参阅the timezone tag wiki 中的“时区!= 偏移量”。