当前位置: 首页 > 知识库问答 >
问题:

如何存储重复的日期,记住夏令时

巫健柏
2023-03-14

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

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

我将时区存储在具有“America/New_York”等值的varchar字段中。

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

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

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

但是——我想我会在这里问,希望也许有一个“正常”的问题,或者一个我没有想到的简单的问题。

(cakephp 2.4.x)

共有1个答案

长孙高远
2023-03-14

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

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

我最近在另一个答案中写了这一点,这是少数几个当地时间比UTC更有意义的例外情况之一。主要论点是“闹钟问题”。如果你按UTC设置闹钟,你将在夏令时转换当天早起或晚起一个小时。这就是为什么大多数人按当地时间设置闹钟。

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

  • 重复事件的本地时间,如"08:00"
  • 表示当地时间的时区,如"America/New_York"
  • 循环模式,以对您的应用程序有意义的任何格式,例如每日、双周或当月的第三个星期四等。
  • 下一个即时的UTC日期和时间等效,尽你所能投射它。
  • 也许,但不总是,未来事件UTC日期和时间的列表,预测出一些预定义的未来时期(可能是一周,可能是6个月,可能是一两年,取决于您的需要)。

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

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

需要考虑的另一点是,如果事件被安排在DST回退转换期间发生的本地时间,您必须决定事件是发生在第一个实例(通常)上,还是发生在第二个实例(有时)上,或者两者兼而有之(很少),并在您的应用程序中构建一种机制,以确保事件不会触发两次,除非您希望它这样做。

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

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

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

>

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

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

 类似资料:
  • 问题内容: 我将事件存储在数据库中。我有“开始”和“结束”日期时间,“ tickets_start”和“ tickets_end”(用于票务销售实际开始/结束的时间- 而不是实际事件的开始/结束)。 到目前为止,我已经构建了可以完成所有有趣工作的方法,例如在保存之前将日期/时间转换为GMT,然后返回各自的时区进行显示。 我将时区存储在varchar字段中,其值类似于“ America / New_

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

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

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

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

  • 问题内容: 我想知道用Java最简单的方法来获取将来的夏令时将改变的日期列表。 一种相当灵活的方法是简单地迭代一整年的时间,然后对它们进行TimeZone.inDaylightTime()测试。这将起作用,并且我不担心效率,因为这仅在我的应用每次启动时都需要运行,但是我想知道是否有更简单的方法。 如果您想知道为什么要这样做,那是因为我有一个javascript应用程序,该应用程序需要处理包含UTC