Calendar.csを繰り返し文を1つに纏めてみました

Myoga-SB-SDF-A2

Hello~! ミョウガです!
今回は、「カレンダープログラミングにMyoga、抜錨します!」にある、Calendar.cs(GitHubでは「Calendarold.cs」)の2つの繰り返し文を1つに纏めた時のお話です。

1. 1日の曜日合わせのパディング処理と日付出力を統合してみました

前回書いたプログラムを以下に示します。

using System;

namespace Myoga1012_Cal {
    class Program {
        static void Main( string[] args ) {

            // 現在の日付を取得し、当月1日を表すインスタンスを生成します。
            DateTime now = DateTime.Today;
            DateTime day = new DateTime( now.Year, now.Month, 1 );

            // 1日の曜日に合わせてオフセットします。 
            for( int i = 0; i < ( int )day.DayOfWeek; i++ ) Console.Write( "   " );

            // カレンダーを出力します。
            do {
            // 日付を出力します(最大2桁なので、最小フィールド幅を3と指定し、右寄せかつ日付間にスペースを開けます)。
                Console.Write( "{0, 3}", day.Day );
                // dayが土曜日または月末日であれば、改行します。
                if( day.DayOfWeek == DayOfWeek.Saturday ||
                    day.Day == DateTime.DaysInMonth( now.Year, now.Month ) ) Console.WriteLine();

                // dayを1日分進めて、月が変わるまで繰り返します。
            } while( ( day = day.AddDays( 1.0 ) ).Month == now.Month );
        }
    }
}

ここで、12行目の1日の曜日合わせのパディング処理を、15~23行目の日付出力の処理のdo文に入れて、1つの繰り返し文に統合してみました。

using System;

namespace Myoga1012_Cal {
    class Program {
        static void Main( string[] args ) {

            // 現在の日付を取得から当月1日を表すインスタンスを生成します。
            DateTime now1 = new DateTime( DateTime.Today.Year, DateTime.Today.Month, 1 );
            // 当月1日からその曜日分だけ引きます。
            DateTime curDay = now1.AddDays( -( int )now1.DayOfWeek );

            // カレンダーを出力します。
            do {
                // 日付を出力します(最大2桁なので、最小フィールド幅を3と指定し、右寄せかつ日付間にスペースを開けます)。
                // もし、curDayが前月であれば、空白スペースを出力します。
                // こうすることで1日の曜日に合わせてオフセットすることができます。
                if( curDay >= now1 ) Console.Write( "{0, 3}", curDay.Day ); else Console.Write( "   " );
                // curDayが土曜日または当月末日であれば、改行します。
                if( curDay.DayOfWeek == DayOfWeek.Saturday ||
                    curDay.Month == now1.Month && curDay.Day == DateTime.DaysInMonth( now1.Year, now1.Month ) ) Console.WriteLine();

                // curDayを1日分進めて、翌月になるまで繰り返します。
            } while( ( curDay = curDay.AddDays( 1.0 ) ).Month == now1.Month || curDay <= now1 );
        }
    }
}

なお、このプログラムはhttps://gist.github.com/Nia-TN1012/51c59f7cb6661544eee6549f454851b9でも公開されています(※GitHubアカウントの統合のため、ニア側のGistに移動しました)。
コンテストにはこのプログラムで応募しました。

まず、10行目でAddDaysメソッドを使って1日の曜日の分(DayOfWeekプロパティの値)だけ引きます。例えば2014年10月1日は水曜日なので、DayOfWeekプロパティの値は3、すなわち引いた後は2014年9月28日を表すDateTime構造体になります。

次に日付を出力するのですが、条件分岐を使ってcurDayが前月の時は日付の代わりに、半角スペース3つを出力します。こうすることで1日の曜日に合わせてオフセットすることができます。

cal-cs2
1日の曜日合わせのパディング処理と日付出力の統合

あとは19~20行目の土曜日の日付または当月末日を出力した後の改行処理と、23行目の繰り返し条件を最適化するだけです。
特に月末日の改行では、前月の末日で改行しないように、curDayとnow1のMonthプロパティの値を比較しています。

こうすることで、1つの繰り返し文でカレンダーを出力することができます。コード量的にはあまり変わってないですが・・・(;・∀・)

[END]

コメント

タイトルとURLをコピーしました