9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

様々な言語で月末の日付を求める(C#,Java,Ruby,Javascript,VBA,Excel,MySQL,SQLite3,Oracle)

Last updated at Posted at 2019-06-22

はじめに

業務用のシステムやツールの開発をしていると、例えば「請求書中の請求日」や「締め処理の実行日」などで、月末日が必要になることが時々あります。
そこで、様々な言語で月末の日付を求める代表的な方法を調べてみました。

C#

  • DateTime構造体のDaysInMonthメソッドを使って「その月の日数」を求めて、次に求めた日数を使ってDateTimeオブジェクトを生成して、月末日を求めます。
  • 【余談】公式APIを見ると「DateTime Struct」と書かれているので、DateTimeクラスではなくDateTime構造体と呼ぶのが正確な表現だと思われます。
LastDayOfMonth.cs
public class LastDayOfMonth
{
    public static void CalcLastDayOfMonth()
    {
        DateTime today = DateTime.Now;
        int days = DateTime.DaysInMonth(today.Year, today.Month);
        System.Console.WriteLine(new DateTime(today.Year, today.Month, days).ToString("yyyy-MM-dd"));
    }
}

Java

  • Java8以降であれば、YearMonthクラスを使って月末日を直接求められます。
  • 現在日を基準にしたい時はYearMonth.now()、任意の年月を指定したい時はYearMonth.of(int year, int month)を使います。
  • LocalDateクラスを使う方法もありますが、YearMonthクラスを使う方が短くてスッキリ書けます。
  • @swordone さん、ご指摘ありがとうございます。
  • Java7の場合、Calendarクラスを使ってゴニョゴニョと処理を書く必要があります。
  • 参考URL:Javaで日時を扱う(Java7まで)
LastDayOfMonth.java
import java.time.LocalDate;
import java.time.YearMonth;

public class LastDayOfMonth {
	public static void main(String[] args) {
		LocalDate lastDay = YearMonth.now().atEndOfMonth();
		System.out.println(lastDay.toString());
	}
}

Ruby

  • Dateクラスのコンストラクタの第3引数に負の値(-1)を指定して、月末日を求めます。
irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> today = Date.today
=> #<Date: 4917313/2,0,2299161>
irb(main):003:0> puts Date.new(today.year, today.month, -1)
2019-06-30
=> nil

Javascript

  • Dateクラスのコンストラクタで「任意の月の翌月の0日」を指定して、月末日を求めます。
var today = new Date();
var last_day = new Date(today.getFullYear(), today.getMonth() + 1, 0);
document.write(last_day);

VBA

  • DateSerial関数で「任意の月の翌月の0日」を指定して、月末日を求めます。
Module1
Public Sub PrintLastDayOfMonth()
  Debug.print DateSerial(Year(Now()), Month(Now())+1, 0)
End Sub

Excel(ワークシート関数)

  • DATE関数を使用する場合、「任意の月の翌月の0日」を指定して月末日を求めます。
  • 以下の式をセルに埋め込めば、今月の月末日を求められます。
  • EOMONTH関数を使用する場合は、「任意の月の0日」を指定して月末日を求めます。
  • DATE関数(翌月)とEOMONTH関数(当月)で指定する月が異なっています。
  • "EOMONTH"とは、"End Of Month"の略語だと思われます。
=DATE(YEAR(NOW()),MONTH(NOW())+1,0)

=EOMONTH(NOW(),0)

MySQL

  • LAST_DAY関数に「任意の日付」を指定して、月末日を求めます。
  • 以下の例ではNOW関数で現在日時を指定していますが、例えば'2019-06-22'など日付文字列を引数に渡すこともできます。
mysql> SELECT LAST_DAY(NOW());
+-----------------+
| LAST_DAY(NOW()) |
+-----------------+
| 2019-06-30      |
+-----------------+
1 row in set (0.00 sec)

SQLite3

  • date関数に「任意の日付の翌月の初日の1日前」を指定して、月末日を求めます。
  • 任意の日付として、'now'で現在日を指定した後...
  • '+1 months'で翌月、'start of month'で月の初日、さらに'-1 days'で1日前に日付をずらしています。
sqlite> select date('now', '+1 months', 'start of month', '-1 days');
2019-06-30

Oracle

  • LAST_DAY関数に「任意の日付」を指定して、月末日を求めます。
  • 以下の例ではSYSDATEで現在日時を指定していますが、例えばTO_DATE('2020/02/19', 'YYYY/MM/DD')などの日付を引数に渡すこともできます。
SELECT LAST_DAY(SYSDATE) FROM DUAL;

LAST_DAY(SYSDATE)
-----------------
29-FEB-20

まとめ

  • 「2019年6月35日」など、存在しない大きな日付を入れて月末日を取得する処理がありそうな気がしましたが、探した限りでは見当たりませんでした。
  • MySQLやOracleの"LAST_DAY"は直感的。
  • 関数の名前が"月末日"な点も、とても分かりやすいと感じました。
  • ExcelのEOMONTH関数も非常にシンプル。
  • 「Excelは機能が乏しくて、月末日を求めるのも大変だろうな...」と予想していましたが、見事に裏切られました。
  • SQLite3は変態的変わり種。
  • date関数は引数が4つも必要な上、自然文のような引数を渡さなければいけません。
言語 使用するクラス/メソッド/関数 月末日の求め方
C# DateTime 「任意の年月」と「その年月における"月の日数"」を指定する。
Java(Java8~) YearMonth 「任意の日付」を指定する。
Ruby Date 「任意の年月の-1日」を指定する。
Javascript Date 「任意の年月の翌月の0日」を指定する。
VBA DateSerial 「任意の年月の翌月の0日」を指定する。
Excel(ワークシート関数) DATE 「任意の年月の翌月の0日」を指定する。
Excel(ワークシート関数) EOMONTH 「任意の年月の0日」を指定する。
MySQL LAST_DAY 「任意の日付」を指定する。
SQLite3 date 「任意の日付の翌月の初日の1日前」を指定する。
Oracle LAST_DAY 「任意の日付」を指定する。

参考URL

9
12
5

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
9
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?