确定给定年份是否为闰年

时间:2017-07-08 11:42:24

标签: ruby if-statement switch-statement case

更新我试图解决的问题需要比Date实现更多一点,因为它需要一种方法来考虑1752年后的Gregorian和1752年之前的Julian日历&# 39;不同的闰年定义。

以下是我的解决方案,它通过了我所有的RSpec,并且对我开始使用的嵌套条件有了相当大的改进:

def leap_year?(year)

  gregorian_year = true if year >= 1752
  julian_year = true if year < 1752

  gregorian_test = true if year % 4 == 0 && year % 100 != 0 || year % 400 == 0
  julian_test = true if year % 4 == 0

  case
  when gregorian_year && gregorian_test
    true
  when julian_year && julian_test
    true
  else
    false
  end
end

原始问题

我写了一个简单,丑陋的嵌套条件来实现以下目的:

要实现以下目标:

返回&#34; true&#34;如果年份符合以下条件:

  1. 可被4整除
  2. AND不是一个世纪年(例如)1900
  3. 除非可被400整除(例如400,800,2000)
  4. 我写了一个丑陋的嵌套条件:

    if year % 4 == 0
      puts "Divisible by four"
      if year % 100 == 0
        puts "Century year"
        if year % 400 == 0
          puts "Quad-century year, leap year"
          true
        else
          "Not a Quad-century year, not a leap year"
          false
        end
      else
        puts "Not a century year, leap year"
        true
      end
    else
      puts "Not divisible by four: not a leap year."
      false
    end
    

    我尝试在条件有条件的情况下实现相同的目标,但未能检测到 2016 的数字为闰年:

    case year
    when (year % 4 == 0 && year % 100 != 0)
      true
    when year % 400
      true
    when year % 4 != 0
      false
    end
    

    两个问题:

    1. 在我的情况下,我做错了什么?
    2. 有没有更好的方法来实现这个目标?

2 个答案:

答案 0 :(得分:2)

如果您的year参数都是布尔值,则从case year移除when

  case
  when (year % 4 == 0 && year % 100 != 0)
    true
  when year % 400 == 0
    true
  else
    false
  end

您可以检查它是否有效:

def is_leap?(year)
  case
  when (year % 4 == 0 && year % 100 != 0)
    true
  when year % 400 == 0
    true
  else
    false
  end
end

require 'date'

p (0..2050).all?{|y| Date.leap?(y) == is_leap?(y)}
# true

此变体可能更具可读性:

def is_leap?(year)
  case
  when year % 400 == 0
    true
  when year % 100 == 0
    false
  when year % 4 == 0
    true
  else
    false
  end
end

最后,你可以写一个没有任何ifcase的表达式:

year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)

答案 1 :(得分:2)

如果您想确定某一年是否为闰年,那么Date课程已经为您Date#leap?实施了这一年:

Date.leap?(2000)
#=> true

# Or, alternatively:

Date.gregorian_leap?(1900)
#=> false

Date.julian_leap?(1900)
#=> true

Ruby文档中的更多信息:Date#leap?

如果您想自己构建它,这应该可行:

def leap_year?(year)
  return false unless year % 4 == 0
  return true unless year % 100 == 0
  year % 400 == 0
end

leap_year?(2016)
#=> true