【问题标题】:comparing a datetime from sql request and Time.now.utc比较来自 sql 请求和 Time.now.utc 的日期时间
【发布时间】:2019-02-27 09:07:30
【问题描述】:

我有一个 jsonb 字段,用于存储令牌过期日期,如下所示:

user.token = {token_expires: Time.now.utc}
user.save

当我这样做时

user.token['token_expires']
=> "2018-09-23T18:21:58.010Z"

结果是 2018-09-23T18:21:58.010Z

如果我在控制台中检查当前日期时间

Time.now.utc
=> 2018-09-23 19:06:20 UTC

结果是 2018-09-23 19:06:20 UTC

现在的问题是当我尝试运行以下请求时:

User.where("""users.token ->> 'token_expires' <= :current_time""",
                                           current_time: Time.now.utc).pluck(:id)
=> []  # returns an empty array/result

所以令牌过期日期是 2018-09-23T18:21:58.010Z 并且当前日期时间是 2018-09-23 19:06:20 UTC 但是在请求中,当我尝试获取拥有token_expires &lt; Time.now.utc 的用户时,我什么也没得到!期望得到我第一次创建的用户

【问题讨论】:

标签: ruby-on-rails postgresql


【解决方案1】:

我会在这里回答我的问题,希望有人觉得它有用

每个人都需要了解的是,日期或日期时间存储在 json/jsonb 字段中作为字符串,通常我的代码发生了什么

user.token = {token_expires: Time.now.utc}
user.save

是 Rails 隐式 convert Time.now.utc to iso8601 存储为字符串,这就是为什么当我这样做时(在我的控制台中)

user.token['token_expires']

我得到 "2018-09-23T18:21:58.010Z" 这是我之前 Time.now.utc 的 iso8601 格式

我不打算解释为什么 Rails 进行这种转换,但据我了解,建议使用 ISO-8601 格式将日期/日期时间存储在数据库中,特别是对于 json/jsonb 字段,因为它可以易于处理日期或使用 API 时

您可以存储除 ISO-8601 以外的其他格式吗? 是的,你可以,这取决于你的需要,例如,我可以通过在我的代码中传递一个字符串而不是像这样的 datetime 来阻止 Rails 为我进行隐式转换:

user.token = {token_expires: Time.now.utc.to_s}
user.save

存储的日期时间(字符串)将如下所示:2018-09-23 18:21:58 UTC

您可能希望将日期存储为 unix 时间,这取决于您!

回到我的问题和不返回任何内容的查询,我的查询如下:

User.where("""users.token ->> 'token_expires' <= :current_time""",
                                       current_time: Time.now.utc).pluck(:id)

在 sql 查询中,我比较的 Time.now.utc (current_time) 变成了这样的 2018-09-23 22:21:18.952113 而数据库中的值 (jsonb 字段) 具有不同的格式 (iso8601) 这就是我得到的原因结果什么都没有。

因此,为了解决这个问题,我必须将当前时间 (Time.now.utc) 存储为字符串,方法是使用 .to_s Time.now.utc.to_s 显式转换它,并防止 Rails 将其转换为 iso。 ..

第二种解决方案是在SQL查询中将iso日期时间转换为时间戳格式,如下所示:

User.where("""(users.token ->> 'token_expires')::timestamp <= :current_time""",
                                       current_time: Time.now.utc).pluck(:id)

以下是帮助我得出这个结论的其他相关问题:

Is ISO8601 the best date-format for PostgreSQL jsonb when i want to filter by the date?

JSONb dates: actual dates internally?

Converting UTC timestamp to ISO 8601 in Ruby

【讨论】:

    猜你喜欢
    • 2021-08-10
    • 2013-03-02
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2015-07-20
    相关资源
    最近更新 更多