2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

閏年を判定したいのか、29という値が欲しいのか

Last updated at Posted at 2025-01-08

はじめに

個人的な話です。
VBAで指定した年の各月の日数を取得する機能が必要になり、
閏年(うるう年)のことを考慮した実装をしました。

2024年の閏年が終わり、今更ではあるのですが、
備忘録として書かせていただきます。

よくみかける判定方法

Function IsLeapYear(iYear As Integer) As Boolean
    If (iYear Mod 400 = 0) Then
        IsLeapYear = True
    ElseIf (iYear Mod 100 = 0) Then
        IsLeapYear = False
    ElseIf (iYear Mod 4 = 0) Then
        IsLeapYear = True
    Else
        IsLeapYear = False
    End If
End Function

・西暦が4で割り切れる、かつ、100で割り切れない
・西暦が400で割り切れる
のどちらかに当てはまれば閏年、当てはまらない場合は通常年と判定するやり方です。

これを使っても良かったのですが、
再度判定結果からTrueの場合は29日、Falseの場合は28日を返すのは
気が引けるな~ということで他の方法を模索しました。

その1.DateSerial関数を使う方法

20XX/3/1から1を引いた値を求め、3/1の前日つまり2月の最終日を取得するようにしました。
これを使えば閏年かどうかの判定はこちら側で行わなくても済むようになります。
※他の言語では対応していないものもあります

Function GetFebDays(iYear As Integer) As Integer
    GetFebDays = Day(DateSerial(iYear, 3, 1) - 1)
End Function

ちなみに指定した日付から1年の間に閏年が含まれているか判定し、
2月の日数を返したい場合は以下のように書きます。

Function GetFebDays(HopeDay As Date) As Integer
    Dim monthPart As Integer
    Dim yearPart As Integer
    
    monthPart = Month(HopeDay)
    yearPart = year(HopeDay)
    
    '2月を過ぎていたら翌年で計算する
    If monthPart > 2 Then
        yearPart = yearPart + 1
    End If
    
    GetFebDays = Day(DateSerial(yearPart, 3, 1) - 1)
End Function

その2.DateAdd関数を使う方法

その1と同様のやり方ではございますが、こちらでも可能だと思います。

Function GetFebDays(iYear As Integer) As Integer
    GetFebDays = Day(DateAdd("d", -1, DateSerial(iYear, 3, 1))
End Function

おまけ

他の言語(JavaScriptやC#)ではどうなのかも調べてみました

その1.JavaScriptの場合

2月の29番目もしくは3月の0番目を指定し、
存在する場合は29を返すというやり方もあります。

function isLeapYear(year) {
  return new Date(year, 1, 29).getDate() === 29;
}

function isLeapYear(year) {
  return new Date(year, 2, 0).getDate() === 29;
}

その2.C#の場合

そもそもDateTimeクラスにIsLeapYearメソッドが用意されているみたいです。
引数に4桁の数字を指定して使います

bool resule = DateTime.IsLeapYear(2020);

さいごに

浅い感想ですが、いろいろなやり方があるんだな~と思いました。
正直、DateSerial関数を使ったやり方は少しひねっていて初心者ぽくない感じが僕は好きです。笑

ただ先述の通り、言語によっては出来たり出来なかったりするみたいなので、
オーソドックスなModを使ったやり方が書く側もコードを見る側も理解しやすいのかなと思いました。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?