PHP 处理 DST 的时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13698779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 05:54:35  来源:igfitidea点击:

timezone with DST handling by PHP

phpdatetimeutcdsttimezone-offset

提问by Krishna Shetty

I am working on a calendar application. In this users from different time-zones create/view events. I am thinking to follow below method to save event time in UTC and display them in user's local time. Note: user has their preferred timezone setting.

我正在开发一个日历应用程序。在此,来自不同时区的用户创建/查看事件。我想按照以下方法以UTC格式保存事件时间并以用户本地时间显示它们。注意:用户有他们喜欢的时区设置。

To save event start time as UTC timestamp:

将事件开始时间保存为 UTC 时间戳:

$timezone = new DateTimeZone( $user_timezone_name );
$utcOffset = $timezone->getOffset( new DateTime( $event_start_time_string_local ) );
$event_start_timestamp_local = maketime( $event_start_time_string_local );
//Now add/subtract $utcOffset to/from $event_start_timestamp_local to get event's start  //time  timestamp in UTC and save this result in DB.

To get event start time in user's timezone:

要获取用户时区中的事件开始时间:

date_default_timezone_set( $user_timezone_name );
$eventTimeLocalTime = date("Y-m-d H:i:s", $event_start_timestamp_in_UTC );

Where:

在哪里:

user_timezone_name is user's timezone setting.
event_start_time_string_local is event's start time string in local/civil time.
event_start_timestamp_in_UTC is event's start time timestamp in UTC.

My questions:

我的问题:

  • Whether the PHP APIs used above take care of DST for all regions?
  • The DST time itself changes in different years, how does PHP gets information about this? do we need to upgrade PHP? If so do we need to upgrade all or particular PHP library?
  • 上面使用的 PHP API 是否负责所有地区的夏令时?
  • 不同年份的夏令时时间本身是有变化的,PHP如何获取这方面的信息?我们需要升级PHP吗?如果是这样,我们是否需要升级所有或特定的 PHP 库?

References: - does-phps-date-default-timezone-set-adjust-to-daylight-saving- get-timezone-offset-for-a-given-location

参考: - do-phps-date-default-timezone-set-adjust-to-daylight- Saving- get-timezone-offset-for-a-given-location

回答by deceze

You're way too overcomplicating this. To convert between two timezones using DateTime, do this:

你把这个想得太复杂了。要使用在两个时区之间转换DateTime,请执行以下操作:

date_default_timezone_set('Asia/Kolkata'); // YOUR timezone, of the server

$date = new DateTime($input, new DateTimeZone('Asia/Tokyo')); // USER's timezone
$date->setTimezone(new DateTimeZone('UTC'));
echo $date->format('Y-m-d H:i:s');

This converts from a user's local timezone to UTC. To go the other way around, to display the time in the user's local time, swap the two timezones.

这将从用户的本地时区转换为 UTC。反过来,要显示用户本地时间的时间,请交换两个时区。

Yes, PHP takes care of DST. The necessary conversion rules are part of the PHP installation. You can keep them up to date by updating PHP, or by updating the timezonedb.

是的,PHP 负责 DST。必要的转换规则是 PHP 安装的一部分。您可以通过更新 PHP 或更新timezonedb来使它们保持最新状态。

回答by Artur

Yes php api takes into account DST. Most of the time you can safely perform time conversion the way deceze had shown. The problem is that it is not always possible/doable or makes sense. Consider below example - in Poland (in 2013) on Oct 27th at 3am your clock is moved back one hour to switch to standard time (offset UTC+01:00) on March 31st at 2am clock is adjusted forward by 1h to switch to summer time(offset UTC+02:00). Let's now see how 'real time' ticks in Grenwich/UTC and how conversion by PHP from Europe/Warsaw to UTC works:

是的 php api 考虑了夏令时。大多数情况下,您可以像 deceze 展示的那样安全地执行时间转换。问题是它并不总是可能/可行或有意义。考虑以下示例 - 在波兰(2013 年)10 月 27 日凌晨 3 点,您的时钟向后移动 1 小时以切换到标准时间(偏移 UTC+01:00) 3 月 31 日凌晨 2 点时钟向前调整 1 小时以切换到夏季时间(偏移 UTC+02:00)。现在让我们看看 Grenwich/UTC 中的“实时”刻度如何以及 PHP 从欧洲/华沙到 UTC 的转换是如何工作的:

Europe/Warsaw time   offset  UTC                    php2utc conversion   php offset
2013-10-27 01:00:00    +2    2013-10-26 23:00:00    2013-10-26 23:00:00  +2
2013-10-27 01:30:00    +2    2013-10-26 23:30:00    2013-10-26 23:30:00  +2
2013-10-27 02:00:00    +2    2013-10-27 00:00:00    2013-10-27 01:00:00  +1  *
2013-10-27 02:30:00    +2    2013-10-27 00:30:00    2013-10-27 01:30:00  +1  *
2013-10-27 02:59:00    +2    2013-10-27 00:59:00    2013-10-27 01:59:00  +1  *
     3am -> 2am .....................................summer time changes to standard(winter) time @3am we subtract 1h so 3am becomes 2am
2013-10-27 02:00:00    +1    2013-10-27 01:00:00    2013-10-27 01:00:00  +1
2013-10-27 02:30:00    +1    2013-10-27 01:30:00    2013-10-27 01:30:00  +1
2013-10-27 03:00:00    +1    2013-10-27 02:00:00    2013-10-27 02:00:00  +1  
2013-10-27 03:30:00    +1    2013-10-27 02:30:00    2013-10-27 02:30:00  +1  

As you can see between 2am-3am there is no way PHP can know 'which' hour (from before/after adjustment) it is hence cannot reliably convert. Hope this helps someone in his/her deliberations ;-)

正如您在凌晨 2 点到凌晨 3 点之间所看到的,PHP 无法知道“哪个”小时(从调整之前/之后),因此无法可靠地转换。希望这有助于他/她的审议;-)