我刚刚意识到,如果我将特定记录添加到我的MySQL数据库中 - 它将具有服务器的日期/时间而不是特定用户以及它们所在的位置,这意味着我按日期搜索功能是无用的!因为当他们在时区中添加它而不是在服务器时区中添加时,他们将无法搜索。
Codeigniter中是否有一种方法可以全局设置特定于用户位置的时间和日期(可能使用其IP),并且每次调用date()或time()时都会使用用户时区。
我实际要求的可能是如何使我的应用程序依赖于每个用户时区?
也许最好将每个用户的时区存储在他们的个人资料中并有一个标准时间(服务器时间),然后将时间转换为每个用户?
谢谢大家
我认为最简单的方法是为内部数据存储(服务器的时区或UTC)定义时区,并在输出时根据用户的时区转换时间。
我不知道CodeIgniter所以我不能指出你正确的功能。一个突出时区的着名库是Zend_Date:Working with Timezones我还没有使用过这些函数,但它们看起来很有前景。
但是,一旦您知道用户的时区,就不难将一个自己的函数放在一起,在输出日期和/或时间时添加/减去偏移量。
可能相关的问题:
听起来您需要做的是将系统中的所有日期和时间存储为UTC时间(以前称为GMT)。这是世界上所有事物都是通过调整来计算的基准时间。 (例如:中心时间距离UTC约-6小时)
在MySQL中,只要您的服务器和数据库配置了正确的时间和时区设置,您就可以使用UTC_TIMESTAMP()来获取当前的UTC时间。
在PHP中运行此命令将PHP的时间戳设置为UTC(您将在代码中运行它,因此将其放在每个页面或集中索引文件中):
date_default_timezone_set('UTC');
或者您可以直接进入PHP.INI并告诉它全局使用UTC时间。 (如果您在单个PHP安装上有多个网站,这可能无效。
然后在系统中的任何地方,您需要获得当前的UTC时间,您可以调用:
time();
然后,对于系统中的每个用户,您将需要询问他们所处的时区,然后在显示时间时对该用户进行调整。因此,如果是UTC时间下午5:00,我住在美国复活节(-5),那么时间将是5:00 - 5小时=中午12:00。
这可能是一个很长的过程,但是一旦你做到了,你的用户会发现它非常有用,特别是在国际上。
以一个现有的Web应用程序为例,例如WordPress和phpBB。每个用户都有自己的时区设置。
从用户接收内容时,在local_to_gmt()
中使用Date Helper函数,然后使用gmt日期将内容保存到数据库中。获取数据时,您将获得gmt中的时间。获取用户的时区设置,然后显示该时区中的数据。
这样,您就可以避免在两个时区之间进行计算。只需确保服务器的时间设置正确,因此所有数据都在正确的gmt时间内。
更新:
最近我回顾了我工作的最后一个有时区问题的项目。在考虑了各种场景之后,这里是时区问题的解决方案:
WHERE
语句(基于服务器日期的过滤器)和ORDER
(因为此列的值全部在同一时区,即服务器的时区)。这样,我只做1个时区计算,即将用户日期转换为服务器日期。为了显示,我根据服务器的日期时间显示日期。由于所有数据都存储在同一时区,因此可以按保存服务器日期值的列对数据进行排序。
对于已设置时区的用户,可以轻松重新计算数据库中的日期,以便在用户的时区中获取日期时间。顺便说一句,在我的应用程序中,我使用timeago jquery plugins显示日期。此插件需要时间为ISO8601格式(UTC时间)。 CodeIgniter中的local_to_gmt()
函数可用于执行此操作。
显然,英国夏令时(夏令时)的飞跃在编程领域是一个很大的混乱,我确实陷入了这种困惑。
在使用时区敏感系统时,我能找到的最佳解决方案(我会尝试连贯地解释)是这样的:
date_default_timezone_set('Europe/London');
和用户的特定时区。gmmktime();
确保创建的时间戳是UTC,而不是由您设置的时区更改。date();
,因为这会将时间戳转换为正确的时间,并考虑到您设置的时区。gmdate();
与您从数据库中获取或使用$gm_timestamp
创建的gmmktime();
一起使用。我已经写了这篇PHP来帮助理解这种情况。
date_default_timezone_set('UTC');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';
date_default_timezone_set('Europe/London');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';
希望我做得很好,但我对此表示怀疑,因为我仍在努力解决这个问题。
更新:
很高兴我这样做了,因为我现在对用户输入的日期有疑问。
要获得用户输入的日期(考虑到他们的时区)以匹配数据库中的UTC对应日期,您应该通过mktime()
。然后使用gmdate('U', $timestamp);
获取真正的UTC时间戳。 (我认为)
例
从报告方面来看,用户正在使用“欧洲/伦敦”时区。在我们的PHP脚本开始时,我们调用date_default_timezone_set('Europe/London');
,而数据库(以及其中的所有记录)仍然是UTC。
然后,用户通过它发送,他们想要在25/03/2010 10:00到30/03/2010 14:00之间选择添加到数据库的书籍列表。然后PHP脚本通过mktime($hour, $minute, $second, $month, $day, $year)
运行日期变量以生成正确的UTC时间戳。开始日期不会改变,但PHP知道结束日期在BST时区内,因此相应地将时间戳更改为UTC。
当结果返回给用户时,date('r', $date_added)
可用于向用户显示根据设置的时区将书籍添加到数据库的日期。
此链接可能有助于了解何时更改。 http://www.daylightsavingtime.co.uk/
我认为重新计算用户的时间是更好的选择,因为它可以为您提供服务器上的标准化时间,即如果您需要查找某些内容,那么(从您的角度来看)一小时前,您就不会感到困惑美国,亚洲等澳大利亚时间。
只要问他们他们的时区(通常选择在该时区的主要城市),然后重新计算:)
或者,您也可以存储两个时间日期 - 一个用于比较,另一个用于显示,因此您不会在服务器端进行太多计算。
此外,如果重新计算,您可以使用日期助手:http://ellislab.com/codeigniter/user-guide/helpers/date_helper.html
我使用了MySQL内置的时区转换。在数据库中,所有日期时间都存储为UTC。在select查询中,我使用CONVERT_TZ
转换为用户的时区。您可以指定时区代码或小时invervals,如:
SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
但是,问题是这不适合夏令时。这尤其令人沮丧,因为世界上许多地方要么不尊重夏令时,要么在不同的日期兑现它。因此,如果您安装了timezone description tables,您可以使用描述性名称来自动计算夏令时,例如:
SELECT CONVERT_TZ('2004-01-01 12:00:00', 'UTC', 'US/Eastern');
Codeigniter包含一个处理各种日期函数的帮助程序。
命令gmt_to_local()可以帮助你......第三个参数是'daylight_saving'。
Takes a Unix timestamp (referenced to GMT) as input, and converts it to a localized timestamp based on the timezone and Daylight Saving time submitted. Example:
$timestamp = '1140153693';
$timezone = 'UM8';
$daylight_saving = TRUE;
echo gmt_to_local($timestamp, $timezone, $daylight_saving);
将此行添加到应用程序文件夹/ config文件夹中的autoload.php:
$autoload['time_zone'] = date_default_timezone_set('Asia/Kolkata');