PHP日光节约难题
我有一个关于处理夏令时的一般问题。 我想它并不是真正的PHP特定的,但我用PHP编写,所以我认为包含它并没有什么坏处。
我有一个使用jquery fullcalendar构建的日历应用程序。 用户在本地时区查看事件,我的服务器将它们存储为mysql中的UTC日期时间。 (在stackoverflow上的其他问题表明,这是处理时区的最佳方式。)因此,每次用户保存或查看日历上的事件时都会进行转换。 这工作正常,但我很困惑如何最好地处理夏令时。
例如,假设EST时区(东部标准时间)的用户在每天重复3pm不是夏令时的情况下创建活动。 我的PHP代码使用标准的DateTime(和DateTimeZone)类在UTC和EST之间按UTC-5:00进行转换。 夏令时处于活动状态时,时钟将提前一小时,而PHP将按UTC-4:00在UTC和EST之间进行转换。 从用户的角度来看,活动从原来的下午3点转移到下午4点。 这不是我的用户和我想要的。 不管夏令时如何,下午3点的活动都应该在下午3点举行。 处理这个问题的最佳方法是什么? 有没有办法在PHP中忽略夏令时?
我的代码:
$getDate = new DateTime($storedDate, new DateTimeZone('UTC'));
$getDate->setTimezone(new DateTimeZone('America/New_York'));
$getDateString = $getDate->format('Y-m-d H:i:s');
更多信息:(从我的评论下面复制)
- 只存储第一次重复事件。 所有其他事件根据用户请求的日历视图(月,周或日视图)实时创建。 用我编码的方式,它只创建在视图上可见的事件。
- 事情是,我也需要在其他时区保持不变。 为了继续最初的例子,下午3点应该在美国东部时间下午3点(不管夏令时如何),但如果在中央时间观看该事件,则该事件还应该保持在下午2点(不管夏令时是否在日光下)。
本质上,我需要以某种方式忽略夏令时。
你有没有试过看DateTimeZone :: getTransitions()?
http://www.php.net/manual/en/datetimezone.gettransitions.php
特别使用[offset]和[isdst]属性。
以您的EST示例为例,即使在EDT中,即使您在美国东部时间八月,也可以使用-5的EST转换值保存值。
如果他们在1月份查看该值,则将该值拉回5,如果在8月份,则添加4。
这对我假设交换机一致的情况有95%有效。 如果东部决定与中央合并,你可能会有-5 / -4 / -5 / -4 / -5 / -5 / -6 / -5 / -6 / -6的转换 ,这会让事情变得糟糕。
这个没有魔力。 我不知道您的应用程序结构的详细信息,您可能需要尝试在任何一天的任何一天的午夜时加上3个小时,以便任何重复的每日预约仅作为时间存储。
这是一个复杂的问题。 我已经学会了艰难的方式,不是每天都是86,400秒。
在做各种日历应用程序时,我很早就做出了设计决定,这为我节省了很多麻烦。 也就是说,事件的每个实例在数据库中都有一个条目。
一张桌子是用于所有事件信息(标题,描述等)。 另一张表为该事件的每个实例保存一个时间戳。 当某人安排重复事件(比如每周三下午3点)时,我会在每个星期三的时区 (实际上存储为UTC)的下午3:00插入一个实例。 现在,理论上的事件可以永远重复。 我认为对重复进行合理的限制(比如说50或100年)要比计算飞行中事件的所有日期要简单得多。 对于用户来说,它看起来像事件一直持续下去,但在数据库中却没有。 即使你每天都有一个100年的活动,但这只是一个非常狭窄的表中的36,500条记录。
用这种方法你必须考虑例外。 有时候人们会改变事件的一个实例的细节。 在这些情况下,我只是创建了另一个事件并复制了相关细节......因为它实际上是一个单独的事件。 如果你想用团队ID把他们全部绑在一起,你可以。 因为每个实例都有一个单独的行,所以更改事件的单个调度很容易。
我推荐这种方法适用于这样的大多数场景。 它为我节省了很多麻烦,可以依靠数据库处理所有繁重的工作,同时也解决了您的时区问题。
链接地址: http://www.djcxy.com/p/29403.html