Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何存储重复日期并牢记夏令时_Php_Mysql_Cakephp_Datetime_Dst - Fatal编程技术网

Php 如何存储重复日期并牢记夏令时

Php 如何存储重复日期并牢记夏令时,php,mysql,cakephp,datetime,dst,Php,Mysql,Cakephp,Datetime,Dst,我正在数据库中存储事件。我有“开始”和“结束”日期时间、“门票开始”和“门票结束”(用于门票销售实际开始/结束的时间,而不是实际活动的开始/结束时间) 到目前为止,我已经构建了一些方法,可以完成所有有趣的事情,比如在保存之前将日期/时间转换为GMT,然后返回到各自的时区进行显示 我将时区存储在一个varchar字段中,其值类似于“America/New_York” 但是-现在我需要开始处理用户是否希望允许重复事件。我以前做过,没什么大不了的,但从来没有跨越多个时区 起初,我认为这没什么大不了的,

我正在数据库中存储事件。我有“开始”和“结束”日期时间、“门票开始”和“门票结束”(用于门票销售实际开始/结束的时间,而不是实际活动的开始/结束时间)

到目前为止,我已经构建了一些方法,可以完成所有有趣的事情,比如在保存之前将日期/时间转换为GMT,然后返回到各自的时区进行显示

我将时区存储在一个varchar字段中,其值类似于“America/New_York”

但是-现在我需要开始处理用户是否希望允许重复事件。我以前做过,没什么大不了的,但从来没有跨越多个时区

起初,我认为这没什么大不了的,但后来我意识到——如果最初的开始日期是在7月(例如),并且它在一年中每个月重复一次,在某个时候,夏令时将使它成为一个时间,因此从GMT的转换将改变一个不同的时间。一个月,当转换为12:00时,它会将其更改为-5,下一个月,由于DST,它会将其更改为-4

我目前的想法是,我将存储一个“dst”tinyint(1),以确定开始/结束日期是否在dst期间输入,然后在必要时制作一个方法将时间更改一小时

但是-我想我会在这里问,希望这可能是一个“正常的”或一个简单的东西,我没有想到


(cakephp 2.4.x)

首先,请认识到,在现代术语中,您应该说UTC而不是GMT。它们基本上是等价的,只是UTC的定义更为精确。保留术语GMT,以指在冬季月份生效的英国时区中UTC+0偏移部分

现在谈谈你的问题。UTC不一定是存储所有日期和时间值的最佳方式。它对过去的事件或未来的绝对事件特别有效,但对未来的局部事件——特别是未来的重复事件——效果不太好

我最近写过这篇文章,这是当地时间比UTC更有意义的少数例外情况之一。主要论点是“闹钟问题”。如果您按UTC设置闹钟,则在DST转换当天,您将早起或晚起一小时。这就是为什么大多数人按当地时间设置闹钟的原因

当然,如果您使用的是来自世界各地的数据,则不能只存储本地时间。您应该存储一些不同的东西:

  • 重复事件的本地时间,例如“08:00”
  • 表示当地时间的时区,如“美国/纽约”
  • 重复模式,无论是何种格式,对您的应用程序都有意义,例如每天、每两周或每月的第三个星期四,等等
  • 下一个即时UTC日期和时间,以您所能预测的最佳时间为准
  • 也许,但并非总是,未来事件UTC日期和时间的列表,将某个预定义的时间段投射到未来(可能是一周,可能是6个月,可能是一年或两年,取决于您的需要)
对于后两种情况,请理解,如果负责该时区的政府决定更改任何内容,则任何本地日期/时间的UTC等效值都可能发生更改。由于每年都有多个时区数据库更新,因此您需要制定计划定期更新。无论何时更新时区数据,都需要重新计算所有未来事件的UTC等效时间

如果您计划显示跨越多个时区的任何类型的事件列表,使用UTC等效值非常重要。这些是您将查询以构建该列表的值

另一个要考虑的问题是,如果事件被安排在DST回落过渡期间发生的本地时间,则必须决定事件是否发生在第一个实例(通常),或第二个实例(有时),或两者(很少)。并在应用程序中构建一种机制,以确保事件不会触发两次,除非您愿意

如果你在寻找一个简单的答案——对不起,没有。跨时区安排未来事件是一项复杂的任务

替代方法 我让一些人向我展示了一种使用UTC时间进行日程安排的技术,即他们选择本地时间的开始日期,将其转换为UTC进行存储,并存储时区ID。然后在运行时,他们应用时区将原始UTC时间转换回本地时间,然后使用该本地时间计算其他重复出现的次数,就好像它是如上所述最初存储的时间一样

虽然这项技术可行,但缺点是:

  • 如果在运行第一个实例之前有一个时区更新更改了本地时间,那么它将取消整个时间表。这可以通过为“第一”实例选择过去的时间来缓解,这样第二个实例实际上就是第一个实例

  • 如果时间真的是一个“浮动时间”,应该跟随用户四处移动(例如在手机的闹钟中),那么您仍然必须为最初创建它的区域存储时区信息,即使该区域不是您想要运行的区域

  • 它增加了额外的复杂性,但没有任何好处。我将保留这项技术,用于您可能有一个仅适用于UTC的调度器,您正试图将时区支持改造为该调度器的情况


是否有一个好方法来检查日期是否已过,或者其他类似的简单“检查”?以前,如果将所有日期都存储在UTC中,这很简单,因为我可以对照服务器时间进行检查。但现在,它似乎需要额外的步骤。。。有什么建议吗?如果您存储了下一个即时预计UTC时间,那么您可以使用它来查询事件是即将发生还是已经过去。如果通过,那么您可能希望为过去的事件i编写一条新记录