我正在尝试将时区系统集成到我的应用程序中,直到现在为止,我一直在努力避免制作时区感知的应用程序-
但是它是一项强制性要求,因此别无选择。TimeZones只是在我头上。我已经在PHP.net和其他站点(包括但不限于SO)上阅读了多个主题。但是我永远也无法掌握。
因此,我想知道是否有人可以在这里帮助我:(我想要做的是在我的应用程序中使用偏好选项,以允许用户从选择菜单中选择自己的时区,但是该应用程序也应该能够设置/为每个用户相应地选择DST。
请确保这将对仍在努力争取时区的其他人有所帮助,所以即使您认为我是一个完整的小飞象/傻瓜,也请提供尽可能详细的解释。
编辑赏金:
我为这个问题添加了赏金,因为我真的很需要编写PHP /
MySQL应用程序时需要一个有关时区的规范性问题(因此我还要添加MySQL标记)。我已经从很多地方找到了东西,但是最好将它们放在一起。查尔斯的回答很好,但我仍然觉得它缺少一些。这是我想到的一些事情:
DateTime
对象将时间存储在数据库中DATETIME
还是TIMESTAMP
?每个都有什么好处或警告?DATE
?NOW()
。这些是否需要在插入之前或之后以某种方式进行转换?DateTime
对象。直接DateTime::__construct()
使用它是否足够?还是需要使用DateTime::createFromFormat()
?NOW()
),而不必担心时区以确保一切保持一致,该怎么办?如果可能,请尝试将其分成逻辑部分,以使将来的用户更容易找到信息。请确保在必要时提供代码示例。
此答案已更新,以适应赏金。原始的未编辑答案在该行下方。
赏金所有者添加的几乎所有问题都与在时区范围内MySQL和PHP日期时间应如何交互有关。
MySQL仍然具有 可怜的 时区支持,这意味着智能必须在PHP端提供。
NOW()
)被合理处理。始终使用DATETIME
,TIMESTAMP
除非明确要求特殊行为,否则不要使用TIMESTAMP
。这比以前减轻了痛苦。
Y-m-d H:i:s
这解决了 大多数 问题。
最后一件事是笨拙的:
- 如果某人先前已插入数据(例如使用
NOW()
),而不必担心时区以确保一切保持一致,该怎么办?
这真是个烦人。另一个答案指出了MySQL的答案CONVERT_TZ
,尽管我个人通过在选择和更新过程中在服务器本地时区和UTC时区之间切换来做到这一点,因为我很顽固。
该应用程序还应该能够为每个用户自行设置/选择DST。
在现代,您不需要也不 应这样 做。
现代版本的PHP具有DateTimeZone类,该类具有列出命名的timezones的功能。命名时区允许用户选择其实际位置,并使系统根据该位置
自动 确定其DST规则。
您可以将DateTimeZone与DateTime结合使用,以获得一些简单但功能强大的功能。默认情况下,您可以简单地在UTC中存储和使用 所有
时间戳,并将它们转换为显示的用户时区。
// UTC default
date_default_timezone_set('UTC');
// Note the lack of time zone specified with this timestamp.
$nowish = new DateTime('2011-04-23 21:44:00');
echo $nowish->format('Y-m-d H:i:s'); // 2011-04-23 21:44:00
// Let's pretend we're on the US west coast.
// This will be PDT right now, UTC-7
$la = new DateTimeZone('America/Los_Angeles');
// Update the DateTime's timezone...
$nowish->setTimeZone($la);
// and show the result
echo $nowish->format('Y-m-d H:i:s'); // 2011-04-23 14:44:00
通过使用此技术,系统将 自动 为用户选择正确的DST设置,而无需询问用户当前是否在DST中。
您可以使用类似的方法来呈现选择菜单。您可以连续地为单个DateTime对象重新分配时区。例如,此代码此刻将列出区域及其当前时间:
$dt = new DateTime('now', new DateTimeZone('UTC'));
foreach(DateTimeZone::listIdentifiers() as $tz) {
$dt->setTimeZone(new DateTimeZone($tz));
echo $tz, ': ', $dt->format('Y-m-d H:i:s'), "\n";
}
通过使用一些客户端魔术,可以大大简化选择过程。Javascript有一个参差不齐但实用的
Date类,它具有一种标准方法,可以在分钟内获取UTC偏移量。在用户时钟正确的盲目假设下,您可以使用它来帮助缩小可能的时区列表。
让我们将这种方法与自己进行比较。除了推翻他们并不真正在乎的用户之外,您还需要在 每次 操作日期 时间时
实际执行一次日期数学运算。这不仅是次优的,而且是蝙蝠鸟粪的疯狂。强迫用户在需要DST支持时注明需要麻烦和困惑。
此外,如果您想为此使用现代的PHP
DateTime和DateTimeZone框架,则需要使用不建议使用的Etc/GMT...
时区字符串而不是命名时区。这些区域名称可能会从将来的PHP版本中删除,因此这样做是不明智的。我说的都是经验。
tl; dr :使用现代工具集,免除日期数学的恐惧。向用户显示 命名 时区的列表。 将您的日期存储在UTC中
,这不会受到DST的任何影响。将datetimes转换为 display上 用户选择的命名时区,而不是更早。
根据要求,这是一个可用时区的循环,以分钟为单位显示其GMT偏移量。我在这里选择分钟来演示一个不幸的事实:并非所有的补偿都在整个小时内!实际上,有些人在夏令时期间提前了半个小时而不是整整一个小时。以分钟为单位的最终偏移量
应 与Javascript的偏移量匹配Date.getTimezoneOffset
。
$utc = new DateTimeZone('UTC');
$dt = new DateTime('now', $utc);
foreach(DateTimeZone::listIdentifiers() as $tz) {
$local = new DateTimeZone($tz);
$dt->setTimeZone($local);
$offset = $local->getOffset($dt); // Yeah, really.
echo $tz, ': ',
$dt->format('Y-m-d H:i:s'),
', offset = ',
($offset / 60),
" minutes\n";
}
问题内容: 我的服务器时间是格林尼治标准时间(GMT),每当有人在线时,我都会执行以下操作。 所以,我的问题是……每当有人执行某项操作时,它都会将日期/时间存储在用户本地时间中……这给我带来了很多麻烦。 我想要的是将所有内容存储在GMT中,但要让用户在其本地时区查看数据并与之交互。 编辑: 这是我更新用户状态的方法: 这是我将日期戳转换为秒的功能。 最后,我如何比较日期: 问题答案: 这里的技巧是
问题内容: 我正在制作一个需要使用PHP 函数将日期存储在MySQL中的应用程序。 这些日期需要在MySQL中使用函数返回以小时为单位的时差进行比较,例如: 但是问题是– PHP date函数使用PHP时区设置,而该函数从MySQL服务器获取MySQL timezome。 我正在尝试解决此问题: 它仅适用于PHP。 它仅适用于PHP。 此返回为空。 这从MySQL的控制台抛出错误。 而且对于MyS
问题内容: 平台: PHP和mySQL 出于实验目的,我在自己的网站上尝试了很少的XSS注入。考虑这种情况,我可以输入表单textarea。由于这是一个文本区域,因此我可以输入文本和各种(英文)字符。这是我的观察结果: 一个)。如果仅在将数据插入数据库之前才应用strip_tags和mysql_real_escape_string并且不对输入使用htmlentities, 则查询将中断 ,由于异常
问题内容: 我有一个MySQL查询 我想分页显示每页10条结果。我该怎么做? 问题答案: 这是一个不错的起点:
本文向大家介绍php mysql localhost,127.0.0.1和ip区别,包括了php mysql localhost,127.0.0.1和ip区别的使用技巧和注意事项,需要的朋友参考一下 一家之言: localhost与127.0.0.1的区别 localhost与127.0.0.1的区别是什么?相信有人会说是本地ip,曾有人说,用127.0.0.1比localhost好,可以减少一次
问题内容: 我正在写一个基本上使用php和mysql查找经纬度25英里半径范围内的地方的地方,并长期使用它。 我想知道这样的事情如何工作? 我会通过一条经纬度较长的经纬度,并让其只提取经纬度25英里以内且距我的位置数据库较长的纬度。 做这个的最好方式是什么? 编辑:我发现此代码用于计算2点之间的距离。 这是在MYSQL中进行此计算的一种方法,因此我只能在Miles = <25时返回吗? 问题答案: