问题描述
PHP中的时区的一些问题已经在我的脑海里了一段时间,我想知道是否有更好的方法来处理它比我目前正在做的。
所有问题都围绕重建数据库存储日期:
在处理必须支持多个时区(对用户)的网站时,标准化时区最小的存储时间戳我总是存储它与服务器时区使用 CURRENT_TIMESTAMP
属性或 NOW()
功能。
这样,我不必考虑在输入时间戳时为PHP设置什么时区(因为PHP时间函数是时区感知的)。对于每个用户,根据他的偏好,我在我的引导文件中的某个地方设置时区:
date_default_timezone_set($ timezone);
当我要使用php date / code>函数,必须进行某种形式的转换,因为MySQL目前以
Ymd H:i:s
格式存储时间戳。不考虑时区,您可以简单地运行:
$ date = date($ format,strtotime($ dbTimestamp));
问题是
date()
和 strtotime()
都是时区感知函数,这意味着如果PHP时区设置与服务器时区不同,则时区偏移将应用两次(而不是一次)为了处理这个问题,我通常使用 UNIX_TIMESTAMP()
函数来检索MySQL时间戳,这个函数是没有时区感知,允许我直接应用 date()
- 从而只应用一次时区偏移。
我不喜欢这个'hack',因为我不能像通常那样检索这些列,或者使用 *
来获取所有列(有时它会大大简化查询)。此外,有时它不是一个选项使用 UNIX_TIMESTAMP()
(特别是当使用开源包没有很多抽象的查询组成)。
$ b $另一个问题是存储时间戳,当使用 CURRENT_TIMESTAMP
或 NOW()
不是一个选项 - 存储PHP生成的时间戳将存储它与我想避免的时区偏移。
我可能在这里缺少一些基本的东西,但是,到目前为止,我还没有能够提出一个通用的解决方案来处理这些问题,所以我被迫对待他们case-by-case。您的想法非常受欢迎
解决方案几个月前,我们花了一些时间思考这个问题。我们最终得到的技术很简单:
- 以GMT / UTC格式存储日期(例如0时区偏移量)。
- 在从数据库检索后应用当前用户时区偏移量(例如在向用户显示之前或任何时候)。
我们使用Unix时间戳格式。但这没关系。
Some issues with timezones in PHP have been in the back of my mind for a while now, and I was wondering if there are better ways to handle it than what I'm currently doing.
All of the issues revolve around reformating database stored dates:
When dealing with a site that has to support multiple timezones (for users), to normalize the timezone offest of stored timestamps I always store it with the server timezone using the CURRENT_TIMESTAMP
attribute or the NOW()
function.
This way I don't have to consider what timezone was set for PHP when the timestamp was entered (since PHP time functions are timezone aware). For each user, according to his preference I set the timezone somewhere in my bootstrap file using:
date_default_timezone_set($timezone);
When I'm looking to format dates with the php date()
function, some form of conversion has to take place since MySQL currently stores timestamp in the format Y-m-d H:i:s
. With no regard to timezone, you could simply run:
$date = date($format,strtotime($dbTimestamp));
The problem with this is that date()
and strtotime()
are both timezone aware functions, meaning that if the PHP timezone is set differently from the server timezone, the timezone offset will apply twice (instead of once as we would like).
To deal with this, I usually retrieve MySQL timestamps using the UNIX_TIMESTAMP()
function which is not timezone aware, allowing my to apply date()
directly on it - thereby applying the timezone offset only once.
I don't really like this 'hack' as I can no longer retrieve those columns as I normally would, or use *
to fetch all columns (sometimes it simplifies queries greatly). Also, sometimes it's simply not an option to use UNIX_TIMESTAMP()
(especially when using with open-source packages without much abstraction for query composition).
Another issue is when storing the timestamp, when usage of CURRENT_TIMESTAMP
or NOW()
is not an option - storing a PHP generated timestamp will store it with the timezone offset which I would like to avoid.
I'm probably missing something really basic here, but so far I haven't been able to come up with a generic solution to handle those issues so I'm forced to treat them case-by-case. Your thoughts are very welcome
解决方案 Few months ago we spent some time thinking about this. The technique we ended up with is pretty simple:
- Store dates in GMT/UTC (e.g. 0 timezone offset).
- Apply current user timezone offset after retrieval from the database (e.g. before showing to the user or whenever you want).
We use Unix timestamps format. But that doesn't matter.
这篇关于处理PHP中的时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!