在PHP中将时间和日期从一个时区转换为另一个时区

时间:2010-10-11 10:05:05

标签: php timezone

基本上我需要的是一个脚本,当提供时间和时区时,可以在另一个时区返回时间。

我的主要问题是:

  • 从GMT到哪里获得时间偏差 - 是否有可用的公共数据库?
  • 如何同时考虑夏令时(DST)差异。
  • 如何很好地将它全部包装在PHP类中 - 或者是否已经有这样的类?

7 个答案:

答案 0 :(得分:83)

<?php
$date = new DateTime('2000-01-01', new DateTimeZone('Pacific/Nauru'));
echo $date->format('Y-m-d H:i:sP') . "\n";

$date->setTimezone(new DateTimeZone('Pacific/Chatham'));
echo $date->format('Y-m-d H:i:sP') . "\n";
?>

以上示例将输出:

2000-01-01 00:00:00+12:00
2000-01-01 01:45:00+13:45

DateTime Manual on php.net

上找到

编辑: 就像Pekka说的那样:DateTime类从5.2开始存在,你首先必须找出哪些方法是真正实现的,哪一个只存在于5.3上。

答案 1 :(得分:4)

试试这个,它可能会有所帮助:)

function converToTz($time="",$toTz='',$fromTz='')
    {   
        // timezone by php friendly values
        $date = new DateTime($time, new DateTimeZone($fromTz));
        $date->setTimezone(new DateTimeZone($toTz));
        $time= $date->format('Y-m-d H:i:s');
        return $time;
    }

答案 2 :(得分:1)

要从给定的时区转换为所需的时区,我们只需要将时区的差异(以秒为单位)加/减去给定的时区即可。

$my_timestamp = strtotime("2020-09-22 14:07:26");
/*
 Convert timezones difference into seconds
 from -7:00 to +5:30  have 12hrs and 30min difference
 So in seconds, 12.5*60*60 is equaled to 45000 seconds
*/

$time_zone_difference = 45000;

//Use date function to get datetime in your desired formate
echo date("Y-m-d h:i:sa", $my_timestamp + time_zone_difference );

或者我们可以这样写 下面给出的功能是用于其他帮助的。

转换以秒为单位的时区差异(如果在整个项目中是固定的,则可以硬编码):

function timezoneDifferenceInSec( $source_timezone, $required_timezone){
    $a = explode(":",$source_timezone);
    $b = explode(":",$required_timezone);
    $c = (intval($a[0])*60+intval($a[1]))*60;
    $d = (intval($b[0])*60+intval($b[1]))*60;
    $diffsec =0;
    if($c < $d)
        $diffsec = $d-$c;
    else
        $diffsec = $c-$d;
    return $diffsec;
    }

//function call
$differenc = timezoneDifferenceInSec("-07:00", "+05:30");

将DateTime转换为所需时区的功能(如果已知差异):

 //datetime in String and timezone_differe is in int
function convertTimezone( $source_date_time,  $timezone_diff_in_sec){
    return date("Y-m-d h:i:sa", strtotime($source_date_time) + $timezone_diff_in_sec);
 }

 //function call
 $timestamp = "2020-09-22 14:07:26";
 $timezone_difference = 4500; //ie from -07:00 to +05:30

 echo convertTimezone( $timestamp, $timezone_difference);

答案 3 :(得分:0)

我知道它迟到了。对于任何想要简单功能将utc转换为任何本地时区的人来说

function UTCTimeToLocalTime($time, $tz = '', $FromDateFormat = 'Y-m-d H:i:s', $ToDateFormat = 'Y-m-d H:i:s')
{
if ($tz == '')
    $tz = date_default_timezone_get();

$utc_datetime = DateTime::createFromFormat($FromDateFormat, $time, new
    DateTimeZone('UTC'));
$local_datetime = $utc_datetime;

$local_datetime->setTimeZone(new DateTimeZone($tz));
return $local_datetime->format($ToDateFormat);
}

 echo UTCTimeToLocalTime('2015-07-01 13:30:00','America/Denver');

答案 4 :(得分:0)

我想谈谈您的第三项。有一个专门由不可变类组成的库。例如,下面是convert a datetime to another timezone的用法:

(new AdjustedAccordingToTimeZone(
    new FromISO8601('2018-04-25 15:08:01+03:00'),
    new CET()
))
    ->value(); // returns 2018-04-25T13:08:01+01:00

这是该库的基本原理。它从我们使用的语言(通常用名词表示)中挑选出一些概念。您可以通过询问“我需要什么?”之类的问题来更明确地定义它们。

在此示例中,首先,您需要一个要转换的日期时间。因此,您需要一个 datetime 。这意味着存在表示此概念或抽象的接口或抽象类。实际上有一个:ISO8601DateTime。其次,您要创建具有特定属性的特定对象。例如,您要从ISO8601字符串创建日期时间对象。这就是使此特定日期时间与众不同的原因。该属性肯定必须以其名称出现:FromISO8601 extends ISO8601DateTime。对此,您很确定两件事:您正在查看ISO8601中的日期时间,因为此类扩展了同名的抽象类。其次,该特定类是通过ISO8601字符串创建的。

此后,遵循相同的原理,您将根据特定的时区调整了日期时间-因此,类为AdjustedAccordingToTimeZone。第二个参数是要转换为的时区。

这里是与此库有关的quick start entry,欢迎随时contribute使用!

答案 5 :(得分:0)

用于将DateTime转换为所需时区的函数(如果已知各时区之间的秒差): 例如:时间戳记为“ 2020-09-22 14:07:26”。 ID为4500的时区差异(以秒为单位); // ie从-07:00到+05:30

 // timestamp as in String and timezones_diff_in_sec is in int
function convertTimezone( $timestamp,  $timezones_diff_in_sec){
    return date("Y-m-d h:i:sa", strtotime($source_date_time) + $timezones_diff_in_sec);
 }

函数调用(

 //function call
 $timestamp = "2020-09-22 14:07:26";
 $timezone_difference = 4500; //ie from -07:00 to +05:30

 echo convertTimezone( $timestamp, $timezone_difference);

答案 6 :(得分:-1)

这里我使用此功能将日期时间转换为另一个时区。 为了获得最佳效果,如果您将日期时间转换为utc时区,然后转换为所需时区,那么效果会更好。

function ConvertTimezoneToAnotherTimezone($time, $currentTimezone, $timezoneRequired) {
    $dayLightFlag = false;
    $dayLgtSecCurrent = $dayLgtSecReq = 0;
    $system_timezone = date_default_timezone_get();
    $local_timezone = $currentTimezone;
    date_default_timezone_set($local_timezone);
    $local = date("Y-m-d H:i:s");
    /* Uncomment if daylight is required */
    //        $daylight_flag = date("I", strtotime($time));
    //        if ($daylight_flag == 1) {
    //            $dayLightFlag = true;
    //            $dayLgtSecCurrent = -3600;
    //        }
    date_default_timezone_set("GMT");
    $gmt = date("Y-m-d H:i:s ");

    $require_timezone = $timezoneRequired;
    date_default_timezone_set($require_timezone);
    $required = date("Y-m-d H:i:s ");
    /* Uncomment if daylight is required */
    //        $daylight_flag = date("I", strtotime($time));
    //        if ($daylight_flag == 1) {
    //            $dayLightFlag = true;
    //            $dayLgtSecReq = +3600;
    //        }

    date_default_timezone_set($system_timezone);

    $diff1 = (strtotime($gmt) - strtotime($local));
    $diff2 = (strtotime($required) - strtotime($gmt));

    $date = new DateTime($time);

    $date->modify("+$diff1 seconds");
    $date->modify("+$diff2 seconds");

    if ($dayLightFlag) {
        $final_diff = $dayLgtSecCurrent + $dayLgtSecReq;
        $date->modify("$final_diff seconds");
    }

    $timestamp = $date->format("Y-m-d H:i:s ");

    return $timestamp;
}

谢谢。