Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails rails范围中与时区无关的到期日比较_Ruby On Rails_Postgresql_Datetime_Activerecord_Timezone - Fatal编程技术网

Ruby on rails rails范围中与时区无关的到期日比较

Ruby on rails rails范围中与时区无关的到期日比较,ruby-on-rails,postgresql,datetime,activerecord,timezone,Ruby On Rails,Postgresql,Datetime,Activerecord,Timezone,考虑以下情况。我有一个凭证模型,其中包含datetimeactivation\u due\u date字段和用户模型,其中包含有关其位置(时区、UTC偏移)的最新信息。 我想检查他是否请求在任何可用时区的到期日前激活凭证。例如,如果到期日设置为2018年8月28日23:59 UTC 我想在激活前检查他是否在2018年8月28日-当前时区23:59之前请求某项服务,因此我的到期日不是固定的-这取决于用户的位置-在一个地方可以在到期日之后,在另一个地方可以在到期日之前。 我尝试了以下方法 模型/凭证

考虑以下情况。我有一个凭证模型,其中包含datetimeactivation\u due\u date字段和用户模型,其中包含有关其位置(时区、UTC偏移)的最新信息。
我想检查他是否请求在任何可用时区的到期日前激活凭证。例如,如果到期日设置为2018年8月28日23:59 UTC 我想在激活前检查他是否在2018年8月28日-当前时区23:59之前请求某项服务,因此我的到期日不是固定的-这取决于用户的位置-在一个地方可以在到期日之后,在另一个地方可以在到期日之前。
我尝试了以下方法

模型/凭证.rb 我的问题是:

  • 
这是正确的方法吗?如果没有,处理此类案件的适当方式是什么

  • 如何测试这样的范围?在查询执行期间比较日期时间时,当前时间戳可能来自数据库服务器,因此我不确定如何在规范中模拟它


  • 提前感谢。

    您可以只存储用户的时区,而不是偏移量,然后执行以下操作:

    where('activation_due_date > ? ', Time.now.utc.in_time_zone(user.timezone))
    
    其中,时区是中显示的任何有效时区

    rake time:zones
    
    至少,这是一种更像rails的做事方式。但我不认为存储偏移量然后手动将其添加到时间中是一种不好的方法

    为了测试这一点,您可以手动将任何想要输入的日期插入到数据库中。然后,您可以使用类似gem的工具在时间上旅行到该点,并测试您的范围:

    Voucher.create(activation_due_date: '2018-01-02 00:00:00')
    format = '%Y-%m-%d %H:%M:%S %Z'
    time = DateTime.strptime("2018-01-02 00:00:00 Central Time (US & Canada)",format)
    Timecop.travel(time)
    Voucher.before_activation_due.all ...
    

    您可以只存储用户的时区,而不是偏移量,然后执行以下操作:

    where('activation_due_date > ? ', Time.now.utc.in_time_zone(user.timezone))
    
    其中,时区是中显示的任何有效时区

    rake time:zones
    
    至少,这是一种更像rails的做事方式。但我不认为存储偏移量然后手动将其添加到时间中是一种不好的方法

    为了测试这一点,您可以手动将任何想要输入的日期插入到数据库中。然后,您可以使用类似gem的工具在时间上旅行到该点,并测试您的范围:

    Voucher.create(activation_due_date: '2018-01-02 00:00:00')
    format = '%Y-%m-%d %H:%M:%S %Z'
    time = DateTime.strptime("2018-01-02 00:00:00 Central Time (US & Canada)",format)
    Timecop.travel(time)
    Voucher.before_activation_due.all ...
    

    一种方法是将
    激活到期日
    转换为用户的时区。正如你所说,“我的截止日期不是固定的——它取决于用户的位置”

    要将其作为作用域来执行,最简单的方法是使用数据库时区函数。这取决于您使用的数据库,但在PostgreSQL中,它将类似于:-

    where('activation\u due\u date AT TIME ZONE?>NOW()',user.timezone)


    更简单的方法是进行字符串比较

    where('to_char(activation_due_date,'yyyyymmddhh24miss')>?',Time.current.in_时区(user.timezone).strftime(“%Y%m%d%H%m%S”);


    在这种情况下,我们说的是用户在墙上的时间是多少,是否少于数据库中的时间(以UTC“存储”)

    一种方法是将
    激活到期日
    转换为用户的时区。正如您所说的“我的到期日不是固定的,它取决于用户的位置”

    要作为作用域执行此操作,最简单的方法是使用数据库时区函数。这取决于您使用的数据库,但在PostgreSQL中,它类似于:-

    where('activation\u due\u date AT TIME ZONE?>NOW()',user.timezone)


    更简单的方法是进行字符串比较

    where('to_char(activation_due_date,'yyyyymmddhh24miss')>?',Time.current.in_时区(user.timezone).strftime(“%Y%m%d%H%m%S”);

    在本例中,我们要说的是用户在墙上的时间是多少,是否少于数据库中的时间(以UTC“存储”)