php将日期时间转换为UTC
Posted
技术标签:
【中文标题】php将日期时间转换为UTC【英文标题】:php convert datetime to UTC 【发布时间】:2011-01-06 22:21:33 【问题描述】:我需要一种简单的方法将日期时间戳转换为 UTC(从服务器所在的任何时区),希望不使用任何库。
【问题讨论】:
【参考方案1】:使用strtotime 从给定字符串(解释为本地时间)生成时间戳,并使用gmdate 将其作为格式化的UTC 日期返回。
示例
根据要求,这是一个简单的例子:
echo gmdate('d.m.Y H:i', strtotime('2012-06-28 23:55'));
【讨论】:
@cherouvim 觉得没必要,不过还是加了一个……希望对你有帮助。 gmdate() 是我希望很久以前偶然发现的那些 php 函数之一。 nl2br,有人吗? GMT 和 UTC 并不总是相同的。 @JaySheth 实际上,UTC 和 GMT 是同义词。 @poke GMT 尊重夏令时,UTC 不尊重,这就是使用它的原因,因此您不必考虑其他任何因素【参考方案2】:使用日期时间:
$given = new DateTime("2014-12-12 14:18:00");
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 14:18:00 Asia/Bangkok
$given->setTimezone(new DateTimeZone("UTC"));
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 07:18:00 UTC
【讨论】:
问题说将时间戳转换为时间戳,而 DateTime 不接受时间戳作为输入。您必须以某种方式将其转换为字符串,然后再将其转换回来。【参考方案3】:试试getTimezone and setTimezone,看例子
(但这确实使用了一个类)
更新:
没有任何课程,你可以尝试这样的事情:
$the_date = strtotime("2010-01-19 00:00:00");
echo(date_default_timezone_get() . "<br />");
echo(date("Y-d-mTG:i:sz",$the_date) . "<br />");
echo(date_default_timezone_set("UTC") . "<br />");
echo(date("Y-d-mTG:i:sz", $the_date) . "<br />");
注意:您可能还需要将时区设置回原始时区
【讨论】:
您应该只使用gmdate
而不是将默认时区更改为UTC。因为gmdate
自动使用UTC。
-1 因为您不想为此更改全局默认时区。它只是要求产生意想不到的副作用。
@Phill 这里的“sz”是什么?
我认为应该是“Y-m-dTG...”而不是“Y-d-mTG...”
它在 laravel 项目中对我不起作用。它返回相同的日期【参考方案4】:
这样做:
gmdate('Y-m-d H:i:s', $timestamp)
或者干脆
gmdate('Y-m-d H:i:s')
在 UTC 中获取“NOW”。
检查参考:
http://www.php.net/manual/en/function.gmdate.php
【讨论】:
【参考方案5】:如果您的日期格式为 YYYY-MM-HH dd:mm:ss, 您实际上可以通过在“日期时间字符串”的末尾添加 UTC 并使用 strtotime 来转换它来欺骗 php。
date_default_timezone_set('Europe/Stockholm');
print date('Y-m-d H:i:s',strtotime("2009-01-01 12:00"." UTC"))."\n";
print date('Y-m-d H:i:s',strtotime("2009-06-01 12:00"." UTC"))."\n";
这将打印:
2009-01-01 13:00:00
2009-06-01 14:00:00
如您所见,它还解决了夏令时问题。
有点奇怪的解决方法.... :)
【讨论】:
我真的不明白为什么 OP 没有选择你的建议:D
@php_nub_qq 可能是因为它通过更改整个脚本的时区来工作,这可能不是所希望的并且可能会产生意想不到的后果。
@felwithe 如果你跳过第一行就不会了,这只是为了演示【参考方案6】:
将本地时区字符串转换为 UTC 字符串。 例如新西兰时区
$datetime = "2016-02-01 00:00:01";
$given = new DateTime($datetime, new DateTimeZone("Pacific/Auckland"));
$given->setTimezone(new DateTimeZone("UTC"));
$output = $given->format("Y-m-d H:i:s");
echo ($output);
NZDT:UTC+13:00
如果 $datetime = "2016-02-01 00:00:01", $output = "2016-01-31 11:00:01";
如果 $datetime = "2016-02-29 23:59:59", $output = "2016-02-29 10:59:59";
新西兰标准时间:UTC+12:00
如果 $datetime = "2016-05-01 00:00:01", $output = "2016-04-30 12:00:01";
如果 $datetime = "2016-05-31 23:59:59", $output = "2016-05-31 11:59:59";
https://en.wikipedia.org/wiki/Time_in_New_Zealand
【讨论】:
【参考方案7】:如果您不介意使用 PHP 的 DateTime 类,该类从 PHP 5.2.0 开始可用,那么有几种情况可能适合您的情况:
如果您有一个 $givenDt
DateTime 对象想要转换为 UTC,那么这会将其转换为 UTC:
$givenDt->setTimezone(new DateTimeZone('UTC'));
如果您以后需要原始的$givenDt
,您也可以在转换克隆对象之前克隆给定的 DateTime 对象:
$utcDt = clone $givenDt;
$utcDt->setTimezone(new DateTimeZone('UTC'));
如果您只有一个日期时间字符串,例如$givenStr = '2018-12-17 10:47:12'
,那你先创建一个日期时间对象,然后再转换。请注意,这假定$givenStr
在 PHP 配置的时区中。
$utcDt = (new DateTime($givenStr))->setTimezone(new DateTimeZone('UTC'));
如果给定的日期时间字符串与您的 PHP 配置中的时区不同,则通过提供正确的时区来创建日期时间对象(请参阅list of timezones PHP supports)。在这个例子中,我们假设阿姆斯特丹的当地时区:
$givenDt = new DateTime($givenStr, new DateTimeZone('Europe/Amsterdam'));
$givenDt->setTimezone(new DateTimeZone('UTC'));
【讨论】:
【参考方案8】:由于strtotime需要特定的输入格式,所以可以使用DateTime::createFromFormat(需要php 5.3+)
// set timezone to user timezone
date_default_timezone_set($str_user_timezone);
// create date object using any given format
$date = DateTime::createFromFormat($str_user_dateformat, $str_user_datetime);
// convert given datetime to safe format for strtotime
$str_user_datetime = $date->format('Y-m-d H:i:s');
// convert to UTC
$str_UTC_datetime = gmdate($str_server_dateformat, strtotime($str_user_datetime));
// return timezone to server default
date_default_timezone_set($str_server_timezone);
【讨论】:
【参考方案9】:我有时会使用这种方法:
// It is not importnat what timezone your system is set to.
// Get the UTC offset in seconds:
$offset = date("Z");
// Then subtract if from your original timestamp:
$utc_time = date("Y-m-d H:i:s", strtotime($original_time." -".$offset." Seconds"));
所有大多数时间都有效。
【讨论】:
这里有两个问题。首先你不应该减去你应该添加偏移量。其次,如果本地时区当前在 DST 上并且所需的日期不在 DST 上,则这不起作用。偏移量将减少一个小时。或相反亦然。所以是的,这在大多数情况下都有效,但并非总是如此。【参考方案10】:http://php.net/manual/en/function.strtotime.php 或者如果您不需要使用字符串而是使用时间组件,那么 http://us.php.net/manual/en/function.mktime.php
【讨论】:
【参考方案11】:对于 PHP 5 或更高版本,您可以使用 datetime::format 函数(参见文档http://us.php.net/manual/en/datetime.format.php)
echo strftime( '%e %B %Y' ,
date_create_from_format('Y-d-m G:i:s', '2012-04-05 11:55:21')->format('U')
); // 4 May 2012
【讨论】:
【参考方案12】:试试
回显日期('F d Y', strtotime('2010-01-19 00:00:00'));
将输出:
2010 年 1 月 19 日
您应该更改格式时间以查看其他输出
【讨论】:
【参考方案13】:通用规范化函数,用于将任何时间戳从任何时区格式化为其他时区。
对于在关系数据库中存储来自不同时区的用户的日期时间戳非常有用。对于数据库比较,将时间戳存储为 UTC 并与 gmdate('Y-m-d H:i:s')
一起使用
/**
* Convert Datetime from any given olsonzone to other.
* @return datetime in user specified format
*/
function datetimeconv($datetime, $from, $to)
try
if ($from['localeFormat'] != 'Y-m-d H:i:s')
$datetime = DateTime::createFromFormat($from['localeFormat'], $datetime)->format('Y-m-d H:i:s');
$datetime = new DateTime($datetime, new DateTimeZone($from['olsonZone']));
$datetime->setTimeZone(new DateTimeZone($to['olsonZone']));
return $datetime->format($to['localeFormat']);
catch (\Exception $e)
return null;
用法:
$from = ['localeFormat' => "d/m/Y H:i A", 'olsonZone' => 'Asia/Calcutta']; $to = ['localeFormat' => "Y-m-d H:i:s", 'olsonZone' => 'UTC']; datetimeconv("14/05/1986 10:45 PM", $from, $to); // returns "1986-05-14 17:15:00"
【讨论】:
【参考方案14】:作为对Phill Pafford's answer 的改进(我不明白他的'Y-d-mTG:i:sz',他建议恢复时区)。 所以我提出了这个(我通过改变纯文本/文本的 HMTL 格式来复杂化......):
<?php
header('content-type: text/plain;');
$my_timestamp = strtotime("2010-01-19 00:00:00");
// stores timezone
$my_timezone = date_default_timezone_get();
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date)\n";
// changes timezone
date_default_timezone_set("UTC");
echo date("Y-m-d\TH:i:s\Z", $my_timestamp)."\t\t (ISO8601 UTC date)\n";
echo date("Y-m-d H:i:s", $my_timestamp)."\t\t (your UTC date)\n";
// reverts change
date_default_timezone_set($my_timezone);
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date is back)\n";
?>
【讨论】:
你应该edit你的答案来解释如何这改进了Phil的答案。你在代码中做了什么改动,为什么会更好? 更改默认 PHP 时区以转换两个时间戳是一种可行的技巧,但不是一个优雅的解决方案。【参考方案15】:或者你可以试试这个:
<?php echo (new DateTime("now", new DateTimeZone('Asia/Singapore')))->format("Y-m-d H:i:s e"); ?>
这将输出:
2017-10-25 17:13:20 亚洲/新加坡
如果您只想显示只读日期,可以在文本输入框的 value 属性中使用它。
如果您不想显示您的地区/国家/地区,请删除“e”。
【讨论】:
【参考方案16】:按照以下步骤在用户的本地系统中设置任何时区的UTC时间(这将是Web应用程序将不同时区保存为UTC所必需的):
javascript(客户端):
var dateVar = new Date();
var offset = dateVar.getTimezoneOffset();
//getTimezoneOffset - returns the timezone difference between UTC and Local Time
document.cookie = "offset="+offset;
PHP(服务器端):
public function convert_utc_time($date)
$time_difference = isset($_COOKIE['offset'])?$_COOKIE['offset']:'';
if($time_difference != '')
$time = strtotime($date);
$time = $time + ($time_difference*60); //minutes * 60 seconds
$date = date("Y-m-d H:i:s", $time);
//on failure of js, default timezone is set as UTC below
return $date;
..
..
//in my function
$timezone = 'UTC';
$date = $this->convert_utc_time($post_date); //$post_date('Y-m-d H:i:s')
echo strtotime($date. ' '. $timezone)
【讨论】:
以上是关于php将日期时间转换为UTC的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript:将 UTC 日期时间转换为传递时区的日期时间