【发布时间】:2011-04-23 17:48:12
【问题描述】:
基本上我需要的是一个脚本,当提供时间和时区时,它可以返回另一个时区的时间。
我的主要问题是:
- 从哪里获取与 GMT 的时间偏移 - 是否有可用的公共数据库?
- 如何同时考虑夏令时 (DST) 差异。
- 如何将它全部封装在一个 PHP 类中 - 或者是否已经有这样的类可用?
【问题讨论】:
基本上我需要的是一个脚本,当提供时间和时区时,它可以返回另一个时区的时间。
我的主要问题是:
【问题讨论】:
将 DateTime 转换为所需时区的函数(如果已知时区之间的秒数差异): 示例:时间戳为“2020-09-22 14:07:26”。 以秒为单位的时区差异 id 4500; //即从-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);
【讨论】:
要将给定时区转换为所需时区,我们只需将时区差(以秒为单位)加/减到给定时区。
$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);
【讨论】:
我想谈谈你的第三个项目。有一个专门由不可变类组成的库。例如,您可以通过以下方式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
这是这个库背后的基本原理。它从我们使用的语言中挑选出概念,通常用名词表示。您可以通过提出“我需要什么?”之类的问题来更明确地定义它们。
在此示例中,首先,您需要一个要转换的日期时间。所以,你需要一个日期时间。这意味着要么有一个接口,要么有一个抽象类来表示这个概念,或者抽象。实际上有一个:它是ISO8601DateTime。其次,您要创建具有特定属性的特定对象。例如,您想从 ISO8601 字符串创建日期时间对象。这就是让这个特定日期时间与众不同的原因。它的名称中肯定必须包含该属性:FromISO8601 extends ISO8601DateTime。看这个,你很确定两件事:你正在查看 ISO8601 中的日期时间,因为这个类扩展了一个同名的抽象类。其次,这个特定的类是从 ISO8601 字符串创建的。
之后,遵循相同的原则,您可以根据特定时区调整日期时间 - 因此是 AdjustedAccordingToTimeZone 类。第二个参数是你要转换的时区。
这里是关于这个库的quick start entry,欢迎随时contribute!
【讨论】:
试试这个,它可能会有所帮助:)
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;
}
一点说明: 该函数接受 3 个输入,即要转换的时间、要转换到的时区、当前时区,并以指定的格式返回输出。
【讨论】:
echo converToTz('2021-08-20 15:47:00', 'Europe/London', 'UTC');
我知道已经晚了。对于任何想要简单功能将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');
【讨论】:
在这里,我使用此功能将日期时间转换为另一个时区。 为了获得最佳结果,如果您将日期时间转换为 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;
}
谢谢。
【讨论】:
<?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
编辑: 就像 Pekka 说的:DateTime 类从 5.2 开始存在,您首先必须找出哪些方法是真正实现的,哪些只从 5.3 开始存在。
【讨论】: