Help us understand the problem. What is going on with this article?

現在の日付から、その月初めの曜日を求めてみよう

More than 3 years have passed since last update.

こんにちはー!ニアです。
今回は現在の日付から、その月初めの曜日を求める(例:2016年2月20(土)なら、月初め(2016年2月1日)の曜日は月曜日)方法について紹介していきます。

カレンダーアプリ開発にて、月初めの日の位置を調整したい時に活用してみましょう。

1. 日付を扱うクラスの機能で、指定した日付の曜日を取得できる場合

.NETのDateTime構造体やJavaのCalendarクラスなどでは、指定した日付の曜日を取得できる機能があります。

.NETでは、DateTime.NowTodayでもOK)プロパティで現在の日付を取得し、DateTimeのコンストラクターでその月初めの日付を表すインスタンスを生成して、DayOfWeekプロパティで取得します。

DateTime構造体の機能を利用(C#)
using System;
// ...

// 現在の日付を取得します。
var today = DateTime.Now;
// その月初めの日付を表すインスタンスを生成します。
var firstDay = new DateTime( today.Year, today.Month, 1 );
// 以下の文でもOKです。
//var firstDay = today.AddDays( 1 - today.Day );

// 月初めの曜日を取得します。
DayOfWeek firstDate = firstDay.DayOfWeek;

DayOfWeekは列挙体であり、以下の列挙子が定義されています。

列挙子 概要
Sunday 0 日曜日
Monnday 1 月曜日
Tuesday 2 火曜日
Wednesday 3 水曜日
Thursday 4 木曜日
Friday 5 金曜日
Saturday 6 土曜日

Javaでは、Calendar.getInstanceメソッドで現在の日付を取得し、setメソッドでフィードをCalendar.DATEを指定してその月初めの日付に設定し、getメソッドでCalendar.DAY_OF_WEEKを指定して曜日を表す値を取得します。

Calendarクラスの機能を利用(Java)
import java.util.Calendar;
// ...

Calendar today = Calendar.getInstance();
Calendar firstDay = Calendar.getInstance();
firstDay.set( Calendar.DATE, 1 );
int firstDate = firstDay.get( Calendar.DAY_OF_WEEK );

Calendarクラスには、曜日を表すフィールドが定義されています。

フィールド 概要
SUNDAY 1 日曜日
MONDAY 2 月曜日
TUESDAY 3 火曜日
WEDNESDAY 4 水曜日
THURSDAY 5 木曜日
FRIDAY 6 金曜日
SATURDAY 7 土曜日

2. 現在の年月日が分かる場合

現在の年月日が分かる場合、Zellerの公式(式(1))を使って求めます。

$w = y + \lfloor y/4 \rfloor + \lfloor y/400 \rfloor - \lfloor y/100 \rfloor + ( ( 13 * m + 8 ) / 5 + d ) \mod 7 \tag{1}$

※但し、$w$ : 曜日 / $y$ : 年 / $m$ : 月 / $d$ : 日

$w$の値 曜日
0 日曜日
1 月曜日
2 火曜日
3 水曜日
4 木曜日
5 金曜日
6 土曜日
Zellerの公式(C#)
using System;
// ...

// 現在の日付を取得します。
var today = DateTime.Now;

// 月初めの曜日を取得します。
int w = today.Year / 4 + today.Year / 400 - today.Year / 100 +
        ( ( 13 * today.Month + 8 ) / 5 + 1 ) % 7;

3. 現在の日とその曜日が分かる場合

現在の日とその曜日が分かる場合、以下に示す式(2)から月初めの曜日を求めることができます。

$w_1 = ( w_d + 7 - ( d - 1 ) \mod 7 ) \mod 7 \tag{2}$

※但し、$w_1$ : 月初めの曜日 / $d$ : 現在日 / $w_d$ : 現在日の曜日

上記の式は「現在日(d日とします)の曜日」の値($w_d$)と「月初めの日を日曜日とした時の、d日の曜日」の値($( d - 1 ) \mod 7$)との差を求めて、月初めの曜日を算出しています。

$w_1$、$w_d$の値 曜日
0 日曜日
1 月曜日
2 火曜日
3 水曜日
4 木曜日
5 金曜日
6 土曜日
式(2)の方法(C#)
using System;
// ...

// 現在の日付を取得します。
var today = DateTime.Now;

// 月初めの曜日を取得します。
int w = ( ( int )today.DayOfWeek + 7 - ( today.Day - 1 ) % 7 ) % 7;

【裏話】3.の式(2)ができるまで

実物のカレンダーをじっと見つめていた時、「現在日とその曜日と7の余剰を組み合わせれば、月初めの曜日が求められそう」というアイディアがふと思いつき、試しに式を組み立ててみました。

それでは、See you next!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away