在拼音中创建两个日期之间的月份范围

4dc9hkyq  于 2022-10-15  发布在  Ruby
关注(0)|答案(8)|浏览(162)

我需要创建一个月的一系列月的日志文件。因此,我需要给定范围内的所有[年,月]元组
你是如何迭代日期的?
如果我每天都需要迭代,如何做到这一点呢?

agyaoht7

agyaoht71#

例如:

((Date.today - 90)..Date.today).map{|d| [d.year, d.month]}.uniq

# => [[2012, 12], [2013, 1], [2013, 2], [2013, 3]]
qpgpyjmq

qpgpyjmq2#

Ruby Date支持生成连续的日期,并提供了可用于高效迭代数月的next_month方法。
下面是一个适应输入精度的泛型方法:

require 'date'

def date_tuples(from,to)
  prec   = from.size
  start  = Date.new(*from)
  finish = Date.new(*to)

  filter_on = [:day,:mon].first(3-prec)
  filter = ->(d) { filter_on.all? {|attr| d.send(attr) == 1 } }

  (start..finish)
    .select(&filter)
    .map { |d| [d.year,d.mon,d.day].first(prec) }
end

[7] pry(main)> date_tuples([2012],[2015])
=> [[2012], [2013], [2014], [2015]]
[8] pry(main)> date_tuples([2012,10],[2013,3])
=> [[2012, 10], [2012, 11], [2012, 12], [2013, 1], [2013, 2], [2013, 3]]
[9] pry(main)> date_tuples([2012,10,25],[2012,11,6])
=> [[2012, 10, 25],
 [2012, 10, 26],
 [2012, 10, 27],
 [2012, 10, 28],
 [2012, 10, 29],
 [2012, 10, 30],
 [2012, 10, 31],
 [2012, 11, 1],
 [2012, 11, 2],
 [2012, 11, 3],
 [2012, 11, 4],
 [2012, 11, 5],
 [2012, 11, 6]]
yfjy0ee7

yfjy0ee73#

我想出了这个解决方案来生成范围内所有[年,月]元组的列表:

first=[2012,10]
last=[2013,03]
(first[0]..last[0]).to_a.product((1..12).to_a).select{|ym|(first..last).cover?(ym)}
=> [[2012, 10], [2012, 11], [2012, 12], [2013, 1], [2013, 2], [2013, 3]]
yc0p9oo0

yc0p9oo04#

start_date = 1.year.ago.to_date
  end_date = Date.current.yesterday
  monthly = [Date.new(start_date.year, start_date.beginning_of_month.month, 1)]
  (start_date..end_date).each do |d|
    month_date = Date.new(d.year, d.next_month.beginning_of_month.month, 1)
    monthly << month_date if monthly.exclude?(month_date) && month_date < end_date - 1.month
  end
  monthly

=> [Fri, 01 Sep 2017, Sun, 01 Oct 2017, Wed, 01 Nov 2017, Fri, 01 Dec 2017, Sun, 01 Jan 2017, Thu, 01 Feb 2018, Thu, 01 Mar 2018, Sun, 01 Apr 2018, Tue, 01 May 2018, Fri, 01 Jun 2018, Sun, 01 Jul 2018, Wed, 01 Aug 2018]

ebdffaop

ebdffaop5#

require 'date'
Time.new(2011).to_date.upto(Time.now.to_date) do |a|
    puts ""+a.day.to_s+","+a.month.to_s+","+a.year.to_s
end

或者获取您的月/年数组:

require 'date'
result = []
Time.new(2002).to_date.upto(Time.now.to_date) do |a|
    result << [a.month,a.year]
end
result.uniq!

使用Up to方法从Date:http://ruby-doc.org/stdlib-2.0/libdoc/date/rdoc/Date.html#method-i-upto开始

koaltpgm

koaltpgm6#

这是我写的一种解决这个问题的方法。这是为处理散列数据而设计的,例如:{Sun,01 Jan 2012=>58,Wed,01 Feb 2012=>0,Tsinghua,01 Mar 2012=>0},但可以轻松地针对数组数据进行修改。
请参见:https://github.com/StephenOTT/add_missing_dates_ruby,其中我提供了一个工作代码示例
但代码的关键部分是:

def addMissingMonths (datesHash)
    count = 0
    result = {}

    datesHash.keys.each do |x|
        if x != datesHash.keys.last
            (x+1.month).upto(datesHash.keys[count+1]-1.month) do |a|
                result[a.at_beginning_of_month] = 0
            end
        end

        count += 1
    end

    return result.merge!(datesHash)
end

需要查看的关键内容是:(x+1.month).upto(datesHash.keys[count+1]-1.month)

vltsax25

vltsax257#

这里的大多数答案都需要在范围内每天迭代。这意味着,如果您在几年的时间内执行此操作,您可能会有一个包含数千次迭代的循环。
此代码段创建一个循环,其步数与范围内的月份数相同,这样效率更高:

require 'date'

start_date = Date.new(2010, 10)
end_date = Date.new(2011, 4)

current_month = start_date

date_tuples = []

while current_month <= end_date
  date_tuples << [current_month.year, current_month.month]
  current_month = current_month.next_month
end

pp date_tuples 

# => [[2010, 10], [2010, 11], [2010, 12], [2011, 1], [2011, 2], [2011, 3], [2011, 4]]

这种方法的一个奇怪之处是,它只适用于在每月的第一天的日期。因此,如果您有像Date.new(2020, 10, 12)这样的日期,则需要将其转换为每月的第一天

nukf8bse

nukf8bse8#

我有一个略微不同的问题,但它是相关的:我需要在给定的开始和结束之间的几个月。

def month_start_dates_between_years(start_year, end_year)
  years = (start_year..end_year).to_a
  month_tuples = years.product((1..12).to_a)
  return month_tuples.map { |tuple| Date.new(*tuple) }
end

相关问题