当前位置: 首页 > 面试题库 >

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

袁桐
2023-03-14
问题内容

我将事件存储在数据库中。我有“开始”和“结束”日期时间,“ tickets_start”和“ tickets_end”(用于票务销售实际开始/结束的时间-
而不是实际事件的开始/结束)。

到目前为止,我已经构建了可以完成所有有趣工作的方法,例如在保存之前将日期/时间转换为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”
  • 表示当地时间的时区,例如“ America / New_York”
  • 重复模式,无论哪种格式,对于您的应用程序来说都是有意义的,例如每天,每两周或每月的第三个星期四等。
  • 下一个 立即 UTC日期和时间等效,以便可以进行最佳投影。
  • 也许(但不总是)未来时间UTC日期和时间的列表,预示了将来的某个预定义时间段(可能是一周,可能是6个月,可能是一两年,这取决于您的需求)。

对于后两个,请理解,如果负责该时区的政府决定更改任何内容,则可以更改任何本地日期/时间的UTC。由于每年都有多个时区数据库更新,因此您将需要制定一个计划来订阅更新公告并定期更新您的时区数据库。每当您更新时区数据时,都需要重新计算所有未来事件的UTC等效时间。

如果您打算显示跨越多个时区的任何类型的事件列表,那么具有UTC等效项就很重要。这些是您将查询以构建该列表的值。

要考虑的另一点是,如果事件安排为在DST后备过渡期间发生的本地时间进行,则您必须决定该事件是发生在第一个实例(通常)还是第二个实例(有时),或两者(很少),并在您的应用程序中内置一种机制,以确保事件不会触发两次,除非您希望这样做。

如果您正在寻找一个简单的答案-抱歉,没有答案。跨时区安排未来事件是一项复杂的任务。

我也曾有过一些人告诉我的技术,他们
使用UTC时间安排,这是他们选择在本地时间起始日期,将其转换成UTC存储,和时区ID存储为好。然后在运行时,他们应用时区将原始UTC时间转换回本地时间,然后使用该本地时间来计算其他递归,就好像它是最初存储的上述那样。

尽管此技术 有效 ,但缺点是:

  • 如果有一个时区更新会在运行第一个实例之前更改本地时间,那么它将使整个计划失效。可以通过为“第一个”实例选择过去的时间来减轻这种情况,以使第二个实例实际上是第一个实例。

  • 如果时间确实是应该跟随用户的“浮动时间”(例如在手机的闹钟中),则您仍然必须存储最初创建时区的时区信息-即使那不是您要在其中运行的区域。

  • 它增加了额外的复杂性而没有任何好处。对于可能要使用时区支持的仅UTC调度程序的情况,我会保留此技术。



 类似资料:
  • 我将事件存储在我的数据库中。我有“开始”和“结束”日期时间、“tickets_start”和“tickets_end”(用于门票销售实际开始/结束的时间,而不是实际事件的开始/结束)。 到目前为止,我已经构建了一些方法来完成所有有趣的事情,比如在保存之前将日期/时间转换为GMT,然后返回到各自的时区进行显示。 我将时区存储在具有“America/New_York”等值的varchar字段中。 但是

  • 我想编写一个存储过程来将数据插入到表中,并检查是否已经存在相同的数据? 如果是,则异常抛出为已经存在。但我不知道应该在哪里添加异常。请帮忙。

  • 我读过很多关于的文章。这里有一个很好的。本文建议将datetime存储在两个独立的列中,一个列用于UTC datetime,另一个列用于本地datetime,另一个列用于本地时区。如果我正确理解的话,datetime指的是用户/客户机的datetime和时区。现在我知道可以使用保存UTC日期时间。但是如何使用PHP保存本地日期时间和时区呢?我需要一个方向。

  • 这是我的Firebase结构 我想在每个用户的第二个名字下面的“预订”下存储一天中的日期和时间,然后选择一天中的日期和时间。 这是我到目前为止用错误的方法得到的结果。它在名为“MyBookings”的单独子节点下设置日期 基本上,我所做的是单击一个显示日期和时间选择器的EditText,我需要将该日期存储在Firebase实时数据库中。 这是我的Firebase参考,我知道它是错误的,但不知道如何

  • 日期在Oracle中是如何存储的?例如,我知道大多数系统使用Epoch时间来确定它是什么时间。通过计算距离1970年1月1日有多少秒。Oracle也这样做吗? 我问这个问题的原因是我注意到,如果在Oracle中取两个日期,然后减去它们,就会得到一个浮点数,即两个日期之间的天数。 示例 将返回类似的内容(取决于时间) 现在,Oracle是在进行转换并输出该格式,还是在存储日期时,它离某个时间段有多少

  • 问题内容: 不存在。当我将日期和时间设置为此值时,它不会失败。时间设置为一个小时后。如何通知我该时间不存在。这是时间飞逝的方式 如您所见,此日期将永远不存在。 这是我正在使用的代码 问题答案: 您的样本不会抛出异常,因为它会调整日期时间。该javadoc的状态 这将创建一个与输入的本地日期时间尽可能匹配的分区日期时间。夏时制等时区规则意味着,并非每个本地日期时间都对指定时区有效,因此可以调整本地日