使用NodaTime正确处理打开时间

时间:2013-03-31 22:49:49

标签: c# .net datetime nodatime

我目前正在编写一个相当简单的应用程序来处理企业的开放/关闭时间,并在试图弄清楚如何正确存储信息时遇到严重困难。

我们的大多数关键功能在很大程度上取决于时间绝对完美,所以显然我希望以最好的方式完成工作!

此外,数据将由用户输入,因此如果基础表示稍微复杂一些(例如使用TimeSpans来考虑在午夜过后开放),则需要对用户不可见。

我需要首先存储业务的营业时间,按星期几,与他们相关的时区,例如:

- M:  1000 - 2330
- T:  1000 - 0030
- W:  1900 - 0300
- Th: 2000 - 0300
- F:  2000 - 0800
- Sa: 1000 - 0500
- Su: 1000 - 2300

我目前认为存储它的最佳方法是使用这样的类:

public class OpeningHours
{
    ZonedDateTime OpeningTime { get; set; }
    Period durationOpen { get; set; }

    // TODO: add a method to calculate ClosingTime as a ZonedDateTime
}

然而,这里有两个主要的复杂因素:

  • 我不想存储ZonedDateTime的年,月或日期部分 - 我只关心DayOfWeek。

    当然,我可以将每个值存储在1970年1月1日之后的第一个星期一/星期二等,但这看起来很糟糕而且非常明显错误 - 正如NodaTime的作者非常正确地解释 {{3}在讨论BCL DateTime实现的局限性时。。我也有一种感觉,如果我们稍后尝试使用日期进行任何算术,这可能最终会产生奇怪的奇怪错误。

  • 无论如何,用户将不得不输入ClosingTime。客户端我想我可以做一些简单的事情,比如总是假设ClosingTime是第二天,如果它在OpeningTime之前,但同样,它不是完美的,也没有考虑可能开放超过24小时的地方(例如超市)

我考虑过的另一件事是使用一个有小时/天的表,并让人们突出显示一周的小时数来选择开放时间,但是你仍然遇到同样的问题而只想存储OpeningTime的DayOfWeek部分

任何建议都会受到赞赏,花了最近6个小时阅读我们人类代表时间的滑稽愚蠢的方式让我有点烦恼!

1 个答案:

答案 0 :(得分:19)

我强烈考虑使用LocalTime代替ZonedDateTime,原因如下:

  • 您不是要及时代表单个即时;这些是自然反复出现的模式(没有相关日期)
  • 你并没有试图应对商店在不同时区的不同开放时间的情况;您可能希望将时区与每个商店关联一次,然后您可以随时应用该时区

所以我会有这样的事情(仅显示数据成员;如何理清行为是另一回事):

public class StoreOpeningPeriod
{
    IsoDayOfWeek openingDayOfWeek;
    LocalTime openingTime;
    LocalTime closingTime;
}

请注意,这个完全跟随您显示的原始数据,这总是一个好兆头 - 您既不会添加也不会丢失信息,而且它可能是一种方便的形式。 / p>

如果关闭时间早于开放时间,则假设这已经过了午夜 - 如果这种情况相对不常见,您可能希望为用户添加一个确认框,但在代码中查找和处理它肯定很容易。 / p>