在查询db时处理日期的正确方法

时间:2013-07-24 01:06:30

标签: asp.net datetime timezone

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

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

我正在使用ASP.Net MVC。我还需要确保考虑夏令时。

我知道我不能简单地写一个像:

这样的查询
var data = _context.Jobs
                   .Where(c => c.Modified >= startDate && c.Modified <= endDate);

2 个答案:

答案 0 :(得分:0)

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

...这仍然是一个难题,因为您需要将他们在本地时区输入的时间转换为UTC,这不仅需要知道他们的时区偏移(很容易从浏览器获得),还需要了解实际时区他们在这里你可以为夏令时申请适当的偏移量,而不是他们输入的日期时间,而不是'现在'。

link可能会帮助您确定浏览器的时区,并根据时区进行实际计算,您应该查看Jon Skeet的Noda时间库。

大多数人在夏令时问题上发挥作用,并使用浏览器的时区偏移来调整输入的日期时间值,并假设在查询旧数据时您不关心一小时的错误(或将查询扩展一小时到无论如何包括它。

答案 1 :(得分:0)

有几种不同的方法可以解决这个问题。首先,通过将Job.Modified日期存储为UTC,您正在做正确的事情。所以不要改变它。 :)

方法#1

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

方法#2

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