PHP将日期时间转换为UTC


90

我需要一种简便的方法,可以在不使用任何库的情况下将日期时间戳转换为UTC(从服务器所在的任何时区)。

Answers:


30

尝试getTimezone和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 />");

注意:您可能还需要将时区设置回原始


55
您应该使用gmdate而不是将默认时区更改为UTC。因为会gmdate自动使用UTC。

29
-1,因为您不想为此更改全局默认时区。它只是要求意外的副作用。
Ward Bekker,2010年

@Phill这里的“ sz”是什么?
Shahid Karimi 2015年

2
我认为应该是“ Ym-dTG ...”而不是“ Yd-mTG ...”
Alex Angelico

在laravel项目中,它对我不起作用。它的返回日期相同
Dharmender Tuli

109

使用strtotime从给定的字符串生成时间戳(解释为本地时间),并使用gmdate将其作为格式化的UTC日期返回。

根据要求,这是一个简单的示例:

echo gmdate('d.m.Y H:i', strtotime('2012-06-28 23:55'));

7
也许是一个小例子?
cherouvim 2012年

2
@cherouvim认为没有必要,但无论如何都添加了一个……希望对您有所帮助。

5
gmdate()是我希望很久以前发现的那些PHP函数之一。nl2br,有人吗?
Charlie Schliesser

1
GMT和UTC并不总是相同的。
杰伊·谢思

1
@poke GMT尊重夏令时,UTC则不这样做,因此您无需考虑其他因素
Necro

72

使用DateTime:

$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不接受时间戳作为输入。您将不得不以某种方式将其转换为字符串,然后再将其转换回。
felwithe


14

如果您的日期格式为YYYY-MM-HH dd:mm:ss,则可以通过在“ datetime字符串”末尾添加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

@felwithe如果您跳过第一行,那只是为了演示
php_nub_qq

11

将本地时区字符串转换为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:
    如果$ datetime =“ 2016-02-01 00:00:01”,$ output =“ 2016-01-31 11:00:01”,则UTC + 13:00 ;
    如果$ datetime =“ 2016-02-29 23:59:59”,$ output =“ 2016-02-29 10:59:59”;
  • NZST:
    如果$ datetime =“ 2016-05-01 00:00:01”,$ output =“ 2016-04-30 12:00:01”,则UTC + 12:00 ;
    如果$ datetime =“ 2016-05-31 23:59:59”,$ output =“ 2016-05-31 11:59:59”;

https://zh.wikipedia.org/wiki/Time_in_New_Zealand


5

如果您不介意使用PHP的DateTime类(从PHP 5.2.0开始提供该类),那么可能有几种情况适合您的情况:

  1. 如果您有一个$givenDtDateTime对象要转换为UTC,则它将把它转换为UTC:

    $givenDt->setTimezone(new DateTimeZone('UTC'));
    
  2. 如果$givenDt以后需要原始版本,则可能要在转换克隆的对象之前克隆给定的DateTime对象:

    $utcDt = clone $givenDt;
    $utcDt->setTimezone(new DateTimeZone('UTC'));
    
  3. 如果只有日期时间字符串(例如)$givenStr = '2018-12-17 10:47:12',则首先创建一个日期时间对象,然后将其转换。请注意,这假设$givenStr是在PHP的配置时区中。

    $utcDt = (new DateTime($givenStr))->setTimezone(new DateTimeZone('UTC'));
    
  4. 如果给定的datetime字符串在某个时区中与您的PHP配置中的时区不同,则通过提供正确的时区来创建datetime对象(请参阅PHP支持的时区列表)。在此示例中,我们假设阿姆斯特丹的本地时区:

    $givenDt = new DateTime($givenStr, new DateTimeZone('Europe/Amsterdam'));
    $givenDt->setTimezone(new DateTimeZone('UTC'));
    

4

由于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);

4

我有时使用这种方法:

// 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"));

工程全部 MOST的时间。


3
这里有两个问题。首先,您不应该减去偏移量。其次,如果本地时区当前在DST上并且所需日期不在DST上,则此方法不起作用。偏移量将减少一个小时。或相反亦然。是的,这在大多数情况下有效,但并非总是如此。
2013年



0

尝试

回声日期('F d Y',strtotime('2010-01-19 00:00:00'));

将输出:

2010年1月19日

您应该更改格式时间以查看其他输出


0

通用归一化功能可将任何时区中的任何时间戳格式化为其他时区。对于将不同时区的用户的日期时间戳存储在关系数据库中非常有用。对于数据库比较,将时间戳存储为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"

0

或者,您可以尝试以下操作:

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


0

请按照以下步骤获取用户本地系统中设置的任何时区的UTC时间(Web应用程序将不同的时区保存到UTC时将需要此时间):

  1. Javascript(客户端):

    var dateVar = new Date();
    var offset = dateVar.getTimezoneOffset();
    //getTimezoneOffset - returns the timezone difference between UTC and Local Time
    document.cookie = "offset="+offset;
    
  2. 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)
    

-1

作为对Phill Pafford答案的改进(我不理解他的“ Yd-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"; 
?>

2
您应该编辑您的答案,以解释如何改善Phil的答案。您在代码中做了什么更改,为什么它更好?
科迪·格雷

更改默认的PHP时区以转换两个时间戳是一个可行的技巧,但不是一个很好的解决方案。
Coprolal
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.