気楽なソフト工房

プログラミングについていろいろな記事を書いています。



mykonos2008

Author:mykonos2008
システムエンジニアとして働いている30代の会社員です。
仕事や趣味でプログラムを書いている方の役に立つ記事を書いていきたいと思っています。
ご意見、ご感想はこちらまで
If you are an english speaker,Please visit my english blog.

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
C#の標準APIには「DateTimePicker」などのようにコントロールとして、カレンダーを扱うクラスは有りますが、
データとしてカレンダーを扱うクラスはありません。(たぶん)

最近、Google Calendar APIを利用したカレンダーアプリケーションを作成しようとしているのですが、
そんなクラスが欲しいと思って作成しました。

このクラスで実行する処理は、与えられた日付を含む当月のカレンダーデータを作成するというものです。
通常のカレンダーでは、前月の最終週と当月の最初の週が同じ場合、その週に関しては前月の日付と当月の日付が
混ざった形になります。今回、作成したクラスでは、その場合の処理にも対応しています。

まず、カレンダーデータを管理するために、月を表す「CalendarMonth」、週を表す「CalendarWeek」、日を表す「CalendarDay」
という3つのクラスを作成しました。

[CalendarDay.cs]
    public class CalendarDate
    {
        public int Year
        {
            get;
            set;
        }

        public int Month
        {
            get;
            set;
        }

        public int Day
        {
            get;
            set;
        }
    }

[CalendarWeek.cs]
    public class CalendarWeek
    {
        private CalendarDay[] _days = null;

        public CalendarWeek(CalendarDay[] days)
        {
            _days = days;
        }

        public CalendarDay[] Days
        {
            get
            {
                return _days;
            }

            set
            {
                _days = value;
            }
        }
    }

[CalendarMonth.cs]
    public class CalendarMonth
    {
        public CalendarWeek[] Weeks
        {
            get;
            set;
        }
    }

CalendarMonthクラスがCalendarWeekクラスを、CalendarWeekクラスがCalendarDayクラスを所有する関係です。

そして、指定された日付を含むカレンダーデータを作成する処理が以下になります。

    public class Calendar
    {
        //引数はYYYY-MM-DD形式の文字列
        public CalendarMonth GetCalendarMonth(String date)
        {
            //月の週のリスト
            List weeks = new List();

            //日付を管理する変数
            int day = 1;

            //対象の日付オブジェクトを取得する
            DateTime target = DateTime.Parse(date);

            //当月の日数を求める
            int daysInMonth = DateTime.DaysInMonth(target.Year, target.Month);

            //当月1日の曜日を求める
            DateTime firstDay = target.AddDays(-(target.Day - 1));
            int dayOfWeek = (int)firstDay.DayOfWeek;

            //前月の最終日を取得する
            DateTime prevMonth = target.AddMonths(-1);
            int daysInPrevMonth = DateTime.DaysInMonth(prevMonth.Year, prevMonth.Month);

            //第一週のリストを作成する
            CalendarDay[] weekDays = new CalendarDay[7];

              //今月1日から週の終わりまでを配列にいれる
            for (int i = dayOfWeek; i < 7; i++,day++)
            {
                CalendarDay calDate = new CalendarDay();
                calDate.Year = target.Year;
                calDate.Month = target.Month;
                calDate.Day = day;
                weekDays[i] = calDate;
            }

            //前月月末から週の始めまでを配列に入れる
            for (int i = dayOfWeek - 1, x = daysInPrevMonth; i >= 0; i--, x--)
            {
                CalendarDay calDate = new CalendarDay();
                calDate.Year = prevMonth.Year;
                calDate.Month = prevMonth.Month;
                calDate.Day = x;
                weekDays[i] = calDate;
            }

            weeks.Add(new CalendarWeek(weekDays));

            //月末までの残りの日数を週毎にコレクションに入れる
            for (; day <= daysInMonth;)
            {
                weekDays = new CalendarDay[7];

                for (int i = 0; i < 7; i++)
                {
                    CalendarDay calDate = new CalendarDay();
                    calDate.Year = target.Year;
                    calDate.Month = target.Month;
                    calDate.Day = day;

                    weekDays[i] = calDate;
                    day++;

                    if (day > daysInMonth)
                    {
                        break;
                    }
                }

                weeks.Add(new CalendarWeek(weekDays));
            }

            //月に週を設定する
            CalendarMonth month = new CalendarMonth();
            month.Weeks = weeks.ToArray();

            return month;
        }
    }

前月と当月が混ざる週のロジックは少しややこしいですが、最初に当月1日の曜日を求めて、それより前の曜日を前月の日付で、
後の曜日を当月の日付で埋めるようにしています。

祝祭日に関しては扱っていませんが、Google Calendar APIから取得する方法が有るようですので、
また今度、トライしてみたいと思います。

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://csfun.blog49.fc2.com/tb.php/59-c1fec511

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。