查询数据库中处理日期的正确方法



我想知道在查询数据库时,将日期作为参数处理的正确方法是什么。我的数据库托管在Windows Azure中,我有一个表Job,它是一个具有DateTime数据类型的字段ModifiedDateTime以UTC的形式存储在数据库中。

我想查询基于Modified日期的作业列表。用户将输入开始和结束日期,但它们基于不同的时区。查询数据库时,如何处理日期以与数据完全匹配?

我使用的是ASP.Net MVC。我还需要确保夏令时得到考虑。

我知道我不能简单地写一个查询,比如:

var data = _context.Jobs
                   .Where(c => c.Modified >= startDate && c.Modified <= endDate);

这是一个难题,因为用户的浏览器可能不会报告正确的时间或时区,但假设您可以信任。。。

这仍然是一个难题,因为你需要将他们在本地时区输入的时间转换为UTC,这不仅需要知道他们的时区偏移量(这很容易从浏览器中获得),还需要知道他们所在的实际时区,这样你就可以为夏令时应用适当的偏移量,也可以不为他们输入的日期时间而不是"现在"应用偏移量。

此链接可能有助于您确定浏览器的时区,对于基于时区的实际计算,您应该查看Jon Skeet的Noda时间库。

大多数人都会关注夏令时问题,并使用浏览器的时区偏移量来调整输入的日期时间值,并认为在查询旧数据时,你不在乎一个小时的错误(或者将查询扩展一个小时以将其包括在内)。

有几种不同的方法可以处理此问题。首先,将Job.Modified日期存储为UTC是正确的做法。所以不要改变这一点。:)

方法#1

  • 询问用户的时区,通常是在应用程序中的某种"首选项"或"设置"页面中
  • 如果你想坚持使用Windows时区,你可以从TimeZoneInfo.GetSystemTimeZones生成一个列表。但就我个人而言,我不喜欢使用Windows区域,因为它们有点专有(请参阅时区标签wiki)。相反,我更喜欢让用户使用地图来选择他们的IANA时区,并使用像这样的JavaScript控件
  • 如果使用IANA区域,可以使用jsTimeZoneDetect来猜测用户的时区。这只是一个猜测,所以它可以是默认的选择。但不要将用户锁定在其中。他们应该能够更改它
  • 由于您知道时区,您可以使用TimeZoneInfo或Noda time在服务器上将其输入转换为UTC,然后使用UTC进行查询
  • 优点:可以在任何时区工作;不依赖于计算机的时区设置
  • 缺点:有很多额外的JavaScript。需要更多的用户输入。需要更多的服务器端代码。可能依赖于第三方库

方法#2

  • 使用JavaScript将文本输入解析为实际的JavaScript Date对象
  • 您可能想考虑在解析时使用moment.js以获得更高的灵活性,但这是可选的
  • Datemoment实例中获取UTC时间,并将其传递给服务器
  • 由于输入时间现在是UTC,您可以直接在查询中使用它
  • 优点:时区选择无需额外的用户参与。不需要额外的库(尽管有些是可选的)
  • 缺点:仍然需要一些JavaScript。只能在用户计算机上设置的本地时区中工作。对于夏令时转换附近的某些过去日期,可能会错误地转换值

相关内容

  • 没有找到相关文章

最新更新