如何处理静态时间

时间:2014-03-31 10:28:15

标签: time timezone dst

我正在寻找一些最佳实践来处理和存储静态时间值。

静态时间通常是重复活动的时间,例如体育中心的活动,餐厅的开放时间,电视节目每天播出的时间。

此时间值未绑定到特定日期,不应受夏令时的影响。例如,餐厅将在冬季和夏季的上午11:00开放。

处理这种情况的最佳方法是什么?如何存储这种价值? 我主要对自动TimeZone和DST调整(应该避免)的问题感兴趣,并且保持时间值独立于任何特定日期。

我到目前为止找到的最佳策略是:

  1. 将时间存储为午夜以来的整数秒,
  2. 将时间存储为字符串。
  3. 我读过this question,但主要是关于正常时间值,而不是我描述的用例。

    更新

    我正在处理的图书馆:github

4 个答案:

答案 0 :(得分:2)

关于数据库存储,请按照从最优选到最不喜欢的选项的顺序考虑以下内容:

  • 如果您的数据库支持,请使用TIME类型,例如SQL Server(2008及更高版本),MySQL和Postgres,或Oracle中的INTERVAL HOUR TO SECOND

    < / LI>
  • 为小时和分钟使用单独的整数字段(如果需要,可以使用秒数)。如果您的数据库支持,请考虑使用自定义用户定义类型将它们绑定在一起。

  • 使用带有前导零的24小时格式的字符串,例如"01:23:00""12:00:00""23:59:00"。如果包含秒数,则始终包括秒数。您希望保持字符串按字典顺序排序。不要混合和匹配格式。保持一致。

关于存储从午夜起经过的整数分钟(或秒)的方法,我建议避免它。当你实际存储一段经过的时间时,这种方法很有用,但在存储一天的时间时效果不是很好。考虑:

  • 不是每天都有午夜。在一些时区(例如巴西),在春季DST过渡的那天,时钟从23:59:59到01:00:00。

  • 在拥有DST的任何时区中,&#34;自午夜以来经过的时间&#34;可能骗你。即使午夜存在,如果将10:00保存为&#34; 10小时&#34;,那么这可能是错误的陈述。如果您考虑每年两天参与DST过渡,可能已经过了9个小时或11个小时,因为午夜过去了。

  • 在您的应用程序中的某个时刻,您可能会将此时间值应用于某个特定日期。当你这样做时,如果你正在使用&#34;经过时间&#34;语义,您可能只想将经过的时间添加到相关日期的午夜。由于我刚才提到的原因,这将导致DST过渡日出错。如果您代表的是&#34;时间&#34;在您的存储空间中,您更有可能将它们正确地组合在一起。当然,这在很大程度上取决于您使用的语言和API。

使用其中任何一种,使用重复模式时要小心。假设您存储时间为&#34; 02:00:00&#34;当酒吧每晚关闭。当DST向前弹出时,该时间可能不存在,当它退回时,它将存在两次。当您将时间应用于任何特定日期时,您需要准备好检查这种情况。

您应该做的完全取决于您的使用案例。在许多情况下,明智的做法是在弹簧前进间隙中向前跳一小时,并在后退重叠中选择两个点中的第一个。但是YMMV。

另请参阅DST tag wiki

根据评论,看起来the "tod" gem足以满足您的Ruby代码。

答案 1 :(得分:1)

问题似乎有点模糊,但我会试一试。

一般来说,使用整数对我来说似乎已经足够了。它易于比较,易于添加或减去持续时间(秒),并且节省空间和时间。如果使用面向对象语言,可以考虑将其包装在类中。

据我所知,在C或C ++中没有适合您需求的类。

在.NET世界中,TimeSpan类可能对您有用。它有一些便利,例如:你可以从DateTime.TimeOfDay获得TimeSpan值;您可以添加TimeSpan间隔(TimeSpan);你可以分别得到小时,分钟和秒组件;等

如果使用Python,datime.time也是一个很好的候选者。它专为像您这样的用户设计。

我不知道其他语言的其他优秀候选人。

答案 2 :(得分:1)

为Java讲话:

在Java中,旧的java.util.Date(尽管名称是全球时间戳)或java.util.GregorianCalendar(这是日期和时间的组合)很好地涵盖了您描述的用例。时间和地区等),但是:

Java 8中,您有新的内置类java.time.LocalTime,它可以很好地覆盖您的用例。 Predecessor是外部流行的Java库JodaTime中同名的类LocalTime,它从Java 5开始工作。此外,在我自己的alpha-state-library中,我有类型net.time4j.PlainTime这是类似的,但也提供24:00支持(例如商店开放时间的好)。总而言之,Java是一种非常适合的语言,其中包含有趣的时间库,这些库可以完全按照您的意愿执详细说明:

a)TimeZone和DST调整不由上面提到的Java类处理。相反,只有将这样的普通墙时间转换为包含对时区的引用的org.joda.time.DateTime这样的另一种类型时,才会处理它们。

b)确实,这些时间类也完全独立于日历日期。

c)内部存储策略适用于JSR-310(Java 8):

private final byte hour;
private final byte minute;
private final byte second;
private final int nano;

JodaTime使用本地毫秒的其他策略(自午夜起经过的时间)。

答案 3 :(得分:0)

除非您也知道日/月/年,否则您无法代表时间。没有&#34;不应该受到夏令时的影响&#34;因为有许多复杂的问题要处理,包括闰秒等。正如人类所看到的那样,时间是一件复杂的事情,无法用数学方法轻易处理。

如果你真的需要存储&#34; 11 am&#34;没有任何相关的日期,那么你应该存储什么。只需存储上午11点(或者只是11点,使用24小时)。

然后,如果您需要进行任何数学运算,您必须在执行任何操作之前应用日期。

我也不会存储&#34; 11 am&#34; as&#34;从午夜开始的x秒&#34;。你真的应该使用11个小时,因为这是用户看到的,然后有一个好的日期/时间库将其转换为有用的格式。例如,告诉用户餐厅现在是否开放,您可以将其传递到今天的日期库。