简体   繁体   English

用Date.today查询返回两天

[英]Query with Date.today returns two days

The problem is that the below query returns items from two dates, as if today / now were covering two days, whereas items from only one day should be returned with this query: 问题是下面的查询从两个日期返回项目,好像today / now涵盖两天,而该查询仅返回一天的项目:

Ticket.where("DATE(created_at) = DATE(?)", Time.now.localtime.to_date).map(&:created_at)
      CACHE (0.0ms)  SELECT "tickets".* FROM "tickets"  WHERE (DATE(created_at) = DATE('2014-12-30'))
    => [Mon, 29 Dec 2014 23:15:19 UTC +00:00,
     Mon, 29 Dec 2014 23:17:48 UTC +00:00,
     Mon, 29 Dec 2014 23:18:23 UTC +00:00,
     Mon, 29 Dec 2014 23:18:28 UTC +00:00,
     Mon, 29 Dec 2014 23:19:14 UTC +00:00,
     Mon, 29 Dec 2014 23:20:08 UTC +00:00,
     Tue, 30 Dec 2014 00:11:44 UTC +00:00,
     Tue, 30 Dec 2014 00:12:12 UTC +00:00,
     Tue, 30 Dec 2014 00:14:15 UTC +00:00,
     Tue, 30 Dec 2014 00:15:35 UTC +00:00]

In the above query, Time.now.localtime.to_date returns exactly the same as Time.now.to_date , and Date.today does. 在上面的查询中, Time.now.localtime.to_date返回与Time.now.to_date ,而Date.today则返回。 This might be relevant as I am in the UTC+1 Timezone: 这可能与我在UTC + 1时区有关:

[50] pry(#)> Time.now
=> 2014-12-30 14:03:18 +0100
[51] pry(#)> Time.now.localtime
=> 2014-12-30 14:03:47 +0100
[52] pry(#)> Time.now.localtime.utc
=> 2014-12-30 13:03:52 UTC

Time.now equals Time.now.localtime because I have set activerecord to timestamp in local time with this code in config/application.rb : Time.now等于Time.now.localtime因为我已使用config/application.rb此代码将activerecord设置为本地时间的时间戳:

config.active_record.default_timezone = :local

This is a db on my local machine in development environment, using sqlite3 and rails 4.1.7. 这是开发环境中使用sqlite3和rails 4.1.7的本地计算机上的数据库。

So what's the problem? 所以有什么问题? You have set up default timezone as local, so you are getting the answer from the database, which is relevant for your timezone, since 您已将默认时区设置为本地,因此您将从数据库中获得与您的时区相关的答案,因为

Mon, 29 Dec 2014 23:15:19 UTC +00:00

and

Tue, 30 Dec 2014 00:15:35 UTC +00:00

are placed in the same day ( Tue, 30 Dec 2014 ) in your UTC+1 time zone 被放置在您UTC+1时区的 一天Tue, 30 Dec 2014

Timestamps are always in UTC by default. 默认情况下,时间戳始终为UTC。 If you are 100% sure that your application will be used only in one timezone, and you really want to redefine the default, go to this answer: https://stackoverflow.com/a/15306358/3310560 如果您100%确保仅在一个时区中使用您的应用程序,并且您确实要重新定义默认值,请转到以下答案: https : //stackoverflow.com/a/15306358/3310560

Otherwise, if you use active_record, it's better to compare dates to themselves instead of using vanilla SQL. 否则,如果使用active_record,最好将日期与其自身进行比较,而不要使用原始SQL。

Instead of bringing back ALL the relevant columns of the tickets table ( tickets.* ) and then stripping them down with map(&:created_at) you are much better off using pluck as in: 与其取回tickets表的所​​有相关列( tickets.* ),然后使用map(&:created_at)将其剥离下来,不如使用pluck更好,如下所示:

Ticket.where("DATE(created_at) = DATE(?)", Time.now.localtime.to_date).pluck(:created_at)

This way the DB ends up doing all the work (that it knows how to do well) and you are not bringing back all that extra data. 这样,数据库最终将完成所有工作(知道如何做得很好),而您不会带回所有这些额外的数据。

See more info about pluck here 在此处查看有关pluck更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM