算法找到最佳的日/月/年为间隔在任意时间内? [英] Algorithm to find optimal day/month/year intervals to in an arbitrary timeframe?

查看:126
本文介绍了算法找到最佳的日/月/年为间隔在任意时间内?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If you have a timeframe, say:

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

是否有一个算法,将打破时间内分解成这样的:

Is there an algorithm that will break that timeframe down into this:

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个月块,随机的东西那样。有没有一个正式的名字为这种类型的算法?红宝石例子是真棒,但任何一种语言的作品。

So, maybe instead of dividing the above date range into days/months/years you wanted to divide it up into 5 day and 18 month chunks, something random like that. Is there a formal name for this type of algorithm? A ruby example would be awesome, but any language works.

我已经能够破解起来有些硬codeD红宝石的事情来处理日/月/年的例子:

I've been able to hack together some hardcoded Ruby thing to handle the day/month/year example:

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

...but it seems like there should be an algorithm to abstract this to handle any interval breakdown. Maybe it just boils down to simple math.

推荐答案

这可能是在欺骗,但可以简化code大大利用active_support提供的日期函数。下面是我想出了用active_support一些code。该算法是pretty的简单。找出第一个月的最后一天,找出最后一个月的第一天。然后打印的第一个月,中间分成年,并打印出来,那么打印的最后一个月。当然,这简单的算法中的一些由于边缘情况的方式落下。下面的算法试图解决所有这些边缘情况正常。我希望它能帮助。

This may be cheating but you can simplify the code greatly by using the date functions provided by active_support. Below is some code that I came up with using active_support. The algorithm is pretty simple. Figure out the last day of the first month, figure out the first day of the last month. Then print the first month, split the middle into years and print them, then print the last month. Of course, this simple algorithm falls down in a number of ways due to edge cases. The following algorithm attempts to address each of these edge cases gracefully. I hope that it helps.

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

这篇关于算法找到最佳的日/月/年为间隔在任意时间内?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆