ruby - 在任意时间范围内找到最佳日/月/年间隔的算法?

标签 ruby algorithm

如果你有一个时间表,说:

2009 年 3 月 19 日 - 2011 年 7 月 15 日

是否有一种算法可以将该时间范围分解为:

March 19, 2009  - March 31, 2009    # complete days
April 1, 2009   - December 31, 2009 # complete months
January 1, 2010 - December 31, 2010 # complete years
January 1, 2011 - June 30, 2011     # complete months
July 1, 2011    - July 15, 2011     # complete days

更具体地说,给定任何任意时间范围,甚至精确到秒,是否有一种算法可以将其分成最佳数量的任意大小间隔?

因此,也许您不想将上述日期范围划分为天/月/年,而是将其划分为 5 天和 18 个月的 block ,类似这样的随机 block 。这种算法有正式名称吗?一个 ruby​​ 示例会很棒,但任何语言都可以。

我已经能够将一些硬编码的 Ruby 东西组合在一起来处理日/月/年示例:

...但似乎应该有一种算法来抽象它来处理任何间隔故障。也许它只是归结为简单的数学。

最佳答案

这可能是作弊,但您可以使用 active_support 提供的日期函数大大简化代码。下面是我使用 active_support 想出的一些代码。该算法非常简单。算出第一个月的最后一天,算出最后一个月的第一天。然后打印第一个月,把中间分成几年打印,然后打印最后一个月。当然,由于边缘情况,这个简单的算法在很多方面都失败了。以下算法尝试优雅地解决这些边缘情况中的每一个。希望对您有所帮助。

require 'active_support/all'

# Set the start date and end date
start_date = Date.parse("March 19, 2009")
end_date = Date.parse("July 15, 2011")

if end_date < start_date
  # end date is before start date, we are done
elsif end_date == start_date
  # end date is the same as start date, print it and we are done
  print start_date.strftime("%B %e, %Y")
elsif start_date.year == end_date.year && start_date.month == end_date.month
  # start date and end date are in the same month, print the dates and we
  # are done
  print start_date.strftime("%B %e, %Y"), " - ",
    end_date.strftime("%B %e, %Y"), "\n"
else
  # start date and end date are in different months
  first_day_of_next_month = Date.new((start_date + 1.month).year,
    (start_date + 1.month).month, 1);
  first_day_of_end_month = Date.new(end_date.year, end_date.month, 1);

  # print out the dates of the first month
  if (first_day_of_next_month - 1.day) == start_date
    print start_date.strftime("%B %e, %Y"), "\n"
  else
    print start_date.strftime("%B %e, %Y"), " - ",
      (first_day_of_next_month - 1.day).strftime("%B %e, %Y"), "\n"
  end

  # now print the inbetween dates
  if first_day_of_next_month.year == (first_day_of_end_month - 1.day).year &&
    (first_day_of_end_month - 1.day) > first_day_of_next_month
    # start date and end date are in the same year, just print the inbetween
    # dates 
    print first_day_of_next_month.strftime("%B %e, %Y"), " - ",
      (first_day_of_end_month - 1.day).strftime("%B %e, %Y") + "\n"
  elsif first_day_of_next_month.year < (first_day_of_end_month - 1.day).year
    # start date and end date are in different years so we need to split across
    # years
    year_iter = first_day_of_next_month.year

    # print out the dates from the day after the first month to the end of the
    # year
    print first_day_of_next_month.strftime("%B %e, %Y"), " - ",
      Date.new(first_day_of_next_month.year, 12, 31).strftime("%B %e, %Y"),
      "\n"
    year_iter += 1

    # print out the full intermediate years
    while year_iter < end_date.year
      print Date.new(year_iter, 1, 1).strftime("%B %e, %Y"), " - ",
        Date.new(year_iter, 12, 31).strftime("%B %e, %Y"), "\n"
      year_iter += 1
    end

    # print from the begining of the last year until the last day before the the
    # end month
    print Date.new(first_day_of_end_month.year, 1, 1).strftime("%B %e, %Y"),
      " - ", (first_day_of_end_month - 1.day).strftime("%B %e, %Y"), "\n"
  end

  # finally print out the days of the last month
  if first_day_of_end_month == end_date
    print end_date.strftime("%B %e, %Y"), "\n"
  else
    print first_day_of_end_month.strftime("%B %e, %Y"), " - ",
      end_date.strftime("%B %e, %Y"), "\n"
  end
end

关于ruby - 在任意时间范围内找到最佳日/月/年间隔的算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7164722/

相关文章:

ruby - 为什么哈希值不存在时不抛异常?

java - 苹果推送通知服务(APNS): Feedback Service Response has missing byte?

ruby - 使用 TK GUI 滚动滚动条

mysql - 如何抑制DDL日志

algorithm - MyISAM 是否将所有索引加载到内存中?

python - 在 ngrams 上训练朴素贝叶斯分类器

javascript - 如果大部分功能的执行以输入为条件,那么哪一个是更好的实现方式?

c# - 我可以用什么来确定相似的词或关键词?

c# - 通过整数进行分数计数

algorithm - 从数字数组中获取最小值或最大值的最佳方法是什么?