public enum Day { Sun, Mon, Tue, Wed, Thu, Fri, Sat }public class MyCalender{private readonly int[] endDay = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };private readonly int pivotYear = 1;private readonly Day pivotFirstDay = Day.Mon;public void PrintCalender(int year, int month){//요일 출력--------------------Console.WriteLine(string.Format(" {0}년 {1}월의 달력", year, month));Console.WriteLine();for (int i = 0; i < Enum.GetValues(typeof(Day)).Length; i++){Console.Write(string.Format("{0} ", ((Day)i).ToString()));}Console.WriteLine();//요일 출력--------------------//출력하려는 달의 전달 1번째 요일을 알아냄(예를들어 3월을 입력했으면 3월1일이 무슨 요일인지)Day day = GetFirstDayOfMonth(year, month);int numberOfDays = endDay[month - 1];//윤달 처리if (month == 2 && IsLeapYear(year) == true) numberOfDays++;//여기부터는 그냥 순서대로 출력해주는 부분for (int i = 1; i <= numberOfDays; i++){if (i == 1){for (int j = 0; j < Enum.GetValues(typeof(Day)).Length; j++){if (j < (int)day){Console.Write(string.Format("{0,3} ", ""));}else{break;}}}Console.Write(string.Format("{0,3} ", i));if ((i + (int)day) % 7 == 0) Console.WriteLine();}Console.WriteLine();}private bool IsLeapYear(int year){//400으로 나누어 떨어지면 무조건 윤년 // 아닌경우return ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))) ? true : false;}//출력하려는 달의 1번째 요일 반환private Day GetFirstDayOfMonth(int year, int month){int currentYear = pivotYear;int elapsedDays = (int)pivotFirstDay;while (currentYear <= year){for (int i = 0; i < endDay.Length; i++){if (currentYear == year && month == i + 1)break;elapsedDays += endDay[i];//윤년 체크if (i == 1 && IsLeapYear(currentYear) == true)elapsedDays++;}currentYear++;}//흐른 시간을 7로 나눴을때 나머지를 이용하면 출력하려는 달의 1일이 무슨 요일인지 나옴return (Day)(elapsedDays % 7);}}
.
출력을 원하는 달의 1일이 무슨 요일인지만 알면 그 달의 달력을 쉽게 보여줄 수 있다.
무슨 요일인지는 1년 1월 1일이 월요일이라는 사실을 이용하면 그리 어렵지는 않게 구할 수 있다.
위의 코드 상에서는 알고있는 특정 요일이 1년1월1일 하나 인데, 다른 것들을 또 알고 있다면
(예를 들어 1900년 1월 1일이 월요일이라는 사실)
그걸 피봇 값으로 설정해서 1900년 이후의 날짜를 계산 할때 좀 더 빨라질 것이다.
코드를 짜다 보니 특정 범위 사이에 윤년이 몇개나 있는지 한번에 구할 수 있다면 코드도 엄청 단순해지고
성능도 말도 안되게(O(n) -> O(1)) 엄청 빨리질 것이라는 생각이 들었지만 일단 생각나는대로 바로 짜봤다.
다 만들고 나서 윤년의 갯수를 빠르게 구할 수 있는 방법이 있는지 찾아보니 있었다 ㅋ ㅋ ㅋ ㅋ ㅋ
그렇다. 나는 dog뻘짓을 하고 있었던 것이다. -_- b
'프로그래밍 > C#' 카테고리의 다른 글
스트림이란?? (0) | 2018.07.31 |
---|---|
var (0) | 2018.04.11 |
C# Dictionary의 성능에 대해서. (0) | 2018.03.25 |
C# 자료구조 정리 (0) | 2018.03.24 |
Stack 구현 (0) | 2018.03.21 |