프로그래밍/C#2018. 3. 28. 22:21
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)) 엄청 빨리질 것이라는 생각이 들었지만 일단 생각나는대로 바로 짜봤다.

다 만들고 나서 윤년의 갯수를 빠르게 구할 수 있는 방법이 있는지 찾아보니 있었다 ㅋ ㅋ ㅋ ㅋ ㅋ  

(https://stackoverflow.com/questions/4587513/how-to-calculate-number-of-leap-years-between-two-years-in-c-sharp)


그렇다. 나는 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
Posted by JinFluenza