简体   繁体   English

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

[英]Convert time and date from one time zone to another in PHP

Basically what I need is an script that, when provided with a time and a timezone can return the time in another time zone.基本上我需要的是一个脚本,当提供时间和时区时可以返回另一个时区的时间。

My main issues are:我的主要问题是:

  • Where to get the time offset from GMT from - is there a public database available for this?从哪里获得格林威治标准时间的时间偏移量 - 是否有可用的公共数据库?
  • How to also take into consideration the daylight saving time (DST) differences as well.如何同时考虑夏令时 (DST) 差异。
  • How to nicely wrap it all up inside an PHP class - or is there such a class already available?如何将其全部封装在 PHP 类中 - 或者是否已经有这样的类?
<?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";
?>

The above examples will output:上面的例子将输出:

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

found on DateTime Manual on php.net在 php.net上的DateTime 手册上找到

EDIT: Like Pekka said: The DateTime class exists from 5.2 on and there you first have to find out which of the methods are realy implemented and which one only exist from 5.3 on.编辑:就像 Pekka 说的:DateTime 类从 5.2 开始存在,在那里你首先必须找出哪些方法是真正实现的,哪些只存在于 5.3 之后。

try this, it might help :)试试这个,它可能会有所帮助:)

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;
    }

A bit description: The function takes 3 inputs, time to convert, timezone to convert to, current timezone and returns the output in the specified format.一点说明:该函数接受 3 个输入,转换时间、转换到的时区、当前时区并以指定格式返回输出。

I know its late.我知道已经晚了。 For anyone who would want simple function to convert utc to any local time zone对于任何想要简单函数将 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');

I'd like to address your third item.我想谈谈你的第三个项目。 There is a library consisting exclusively of immutable classes.有一个专门由不可变类组成的库。 For example, here is how you can 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

Here is a rationale behind this library.这是该库背后的基本原理。 It picks out concepts from a language we use, typically denoted by nouns.它从我们使用的语言中挑选出概念,通常用名词表示。 You can define them more explicitly by asking a question like "What do I need?".您可以通过提出诸如“我需要什么?”之类的问题来更明确地定义它们。

In this example, first, you need a datetime you want to convert from.在此示例中,首先,您需要一个要从中转换的日期时间。 So, you need a datetime .所以,你需要一个datetime It means that there is either an interface or an abstract class representing this concept, or abstraction.这意味着有一个接口或一个抽象类表示这个概念,或抽象。 And actually there is one: it's ISO8601DateTime .实际上有一个:它是ISO8601DateTime Second, you want to create specific objects with specific properties.其次,您希望创建具有特定属性的特定对象。 For example, you want to create a datetime object from an ISO8601 string.例如,您想从 ISO8601 字符串创建日期时间对象。 That's what makes this specific datetime special, different from all others.这就是使这个特定日期时间与众不同的原因,与所有其他日期时间不同。 It's the property that surely must be present in its name: FromISO8601 extends ISO8601DateTime .这是其名称中肯定必须存在的属性: FromISO8601 extends ISO8601DateTime Looking at this, you're quite sure about two things: you're looking at the datetime in ISO8601, because this class extends an abstract class of the same name.看看这个,你很确定两件事:你正在查看 ISO8601 中的日期时间,因为这个类扩展了一个同名的抽象类。 and second, this specific class is created from an ISO8601 string.其次,这个特定的类是从 ISO8601 字符串创建的。

After that, following the same principle, you have a datetime adjusted according to specific timezone -- hence the class AdjustedAccordingToTimeZone .之后,遵循相同的原则,您可以根据特定时区调整日期时间——因此类AdjustedAccordingToTimeZone The second parameter is the timezone you want to convert to.第二个参数是您要转换到的时区。

Here is a quick start entry about this library, and feel free to contribute !这是有关此库的快速入门条目,请随时做出贡献

To convert from the given timezone to the desired timezone, we just have to add/subtract the difference of timezones (in SECONDS) to given timezone.要将给定的时区转换为所需的时区,我们只需添加/减去时区的差异(以秒为单位)到给定的时区。

$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 );

or we can write it like Below given functions are for additional help.或者我们可以像下面给出的函数一样编写它以获得额外的帮助。

Convert timezone differences in seconds, (which you can hardcode, if it is fixed throught the project):以秒为单位转换时区差异(如果通过项目修复,您可以对其进行硬编码):

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

Function to convert DateTime into required Timezone (if difference is known):将 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);

Function to convert DateTime into required Timezone (if difference in seconds among the timezones is known): example: Timestamp give is "2020-09-22 14:07:26".将 DateTime 转换为所需时区的函数(如果已知时区之间的秒数差异):示例:时间戳为“2020-09-22 14:07:26”。 Timezones difference in seconds id 4500;时区差异以秒为单位 id 4500; //ie from -07:00 to +05:30 //即从-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 (函数调用(

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

 echo convertTimezone( $timestamp, $timezone_difference);

Here i use this function for converting datetime into another timezone.在这里,我使用此函数将日期时间转换为另一个时区。 For best result if you convert your datetime into utc timezone and then convert into required timezone then it is better result for it.为了获得最佳结果,如果您将日期时间转换为 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;
}

Thank You.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM