【问题标题】:How do I set date time to 1 month ago with DateTime.now.strftime("%Y-%m-%d")?如何使用 DateTime.now.strftime("%Y-%m-%d") 将日期时间设置为 1 个月前?
【发布时间】:2013-08-08 01:06:55
【问题描述】:

我正在尝试使用设置的 Google Analytics(分析)开始日期和结束日期来捕获过去 30 天内的唯一身份访问者。我做了end_date = DateTime.now.strftime("%Y-%m-%d"),如何设置start_date为30天前。

【问题讨论】:

  • 我们需要查看显示您尝试过的示例代码。见sscce.org
  • 问题不是所有的飞蛾都是 30 天。我想知道有什么解决方案吗?

标签: ruby datetime


【解决方案1】:

我意识到这个问题已经很老了,但是对于任何需要知道的人来说,这里有一个干净的方法:

start_date = (Date.now - 30.days).strftime("%Y-%m-%d")

start_date = (Date.now - 1.month).strftime("%Y-%m-%d")

你可以用DateTime.nowTime.now做类似的事情

【讨论】:

  • 我认为这需要active_support/time 或rails?
【解决方案2】:

问题是你对end_date的创建太过分了。

你将它变成了一个字符串,它没有数学能力。相反,将其保留为 DateTime 并继承 add and subtract integers 进行日期数学运算的能力:

require 'date'

datetime_now = DateTime.now
end_date = datetime_now.strftime("%Y-%m-%d") # => "2013-08-06"
end_date.class # => String

end_date = datetime_now # => #<DateTime: 2013-08-06T14:55:20-07:00 ((2456511j,78920s,731393000n),-25200s,2299161j)>
end_date - 30 # => #<DateTime: 2013-07-07T14:55:20-07:00 ((2456481j,78920s,731393000n),-25200s,2299161j)>

请注意,end_date - 30 返回的 DateTime 正好早于 30 天;时间分量被保留。获得所需值后,将值转换为字符串。

【讨论】:

    【解决方案3】:

    使用基本的 Ruby,您可以做到这一点:

    > irb
    require 'date' # needed
    today_minus_30  = Date.today.to_date - 30
    
    # if you need the date as a string
    date_as_string = today_minutes_30.strftime("%Y-%m-%d")
    

    【讨论】:

      【解决方案4】:

      根据 Tin Man 的建议更新:

      在 Ruby 中:

      require 'date'
      end_date = DateTime.now
      start_date = end_date - 30
      formatted_end_date = end_date.strftime("%Y-%m-%d")
      formatted_start_date = start_date.strftime("%Y-%m-%d")
      

      在 Rails 中或者如果需要 active_support/time

      使用 days 和 ago 方法:

      start_date = 30.days.ago
      

      代码如下:

      end_date = DateTime.now
      start_date = end_date - 30.days
      formatted_end_date = end_date.strftime("%Y-%m-%d")
      formatted_start_date = start_date.strftime("%Y-%m-%d")
      

      这样 start_date 正好比 end_date 早 30 天。如果您实例化两个 DateTime,它们将不会正好相隔 30 天。

      daysago 方法可以在 Rails 环境之外通过这一行访问:

      require 'active_support/time'
      

      【讨论】:

      • 您可能想解释daysago 的来源以及如何包含它们。 OP 使用的是直接的 Ruby,所以这些不可用。
      • @theTinMan - 我同意您的评论并相应地更新了我的答案。谢谢。
      • 不,不,不,不建议加载整个 Active Support 代码库,只是为了挑选一些需要的方法。使用DateDateTimeTime 的核心扩展。事实上,请阅读“How to Load Core Extensions”。
      • @theTinMan - 再次更新并感谢您的评论。我无法让require 'active_support/core_ext/date.rb' 工作,但在此线程上找到了require 'active_support/time' 解决方法:stackoverflow.com/questions/4238867/… 谢谢!
      【解决方案5】:

      我建议为此使用辅助方法。类似的东西

      # Gets time range for x number timeunits ago
        def time_range(unit, timeunit = nil)
          if timeunit == "weeks"
            now = Time.zone.now.beginning_of_week
          elsif timeunit == "months"
            now = Time.zone.now.beginning_of_month
          else
            now = Time.zone.now.beginning_of_day
          end
          # Ex: time_range(0, "days") --> Get the time range for today  between the beginning of today and the beginning of tommorow - 1 second
          now - unit.send(timeunit)..now + 1.send(timeunit) - 1.seconds - unit.send(timeunit)
        end
      

      将帮助您请求时间范围。所以当你请求类似的东西时;

      time_range(0, "months")
      

      返回0个月前(本月)的时间范围;

      Thu, 01 Sep 2016 00:00:00 UTC +00:00..Fri, 30 Sep 2016 23:59:59 UTC +00:00
      

      然后您可以简单地查询数据库对象并计算范围内的所有内容;

      Visit.where(started_at: time_range(unit, timeunit)).count
      

      【讨论】:

        猜你喜欢
        • 2021-11-26
        • 1970-01-01
        • 2020-06-22
        • 2017-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        相关资源
        最近更新 更多