U E D R , A S I H C RSS

만년달력/김정현

만년달력 만들기

원하는 년도와 달을 입력하면 달력이 출력된다

설계

TimeInfo에서 시간 정보를 얻어와
CalendarMaker에게 폼을 주고 만들라고 지시한다

소스

public class TimeInfo {
	private static final int BLANK = 1;
	private int[] days= {31,28,31,30,31,30,31,31,30,31,30,31};
	private String[] dayNames= {
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"	
	};

	public int getDaysInMonth(int month) {
		if(!isProperMonth(BLANK, month))
			return 0;
		return days[month-1];
	}

	public int getDaysInYearMonth(int year, int month) {
		if(!isProperMonth(year, month))
			return 0;
		if(month==2 && isSpecialYear(year)) {
			return getDaysInMonth(month)+1;
		}
		return getDaysInMonth(month);
	}

	/*
	 * 윤달은 언제 생기는가? 
	 * 4로 나누어 떨어지면서 100으로 나누어 떨어지지 않는 해. 
	 * 400으로 나누어 떨어지면 무조건 윤달. 
	 */
	private boolean isSpecialYear(int year) {
		if(year%400==0) 
			return true;
		if(year%4==0 && year%100!=0)
			return true;
		return false;
	}

	public int getDaysInYear(int year) {
		if(!isProperMonth(year, BLANK))
			return 0;
		if(isSpecialYear(year)) {
			return 365 + 1;
		}
		return 365;
	}

	private boolean isProperMonth(int year, int month) {
		return ( year > 0 ) && ( 0 < month && month <= 12 );
	}
	private boolean isProperDate(int year, int month, int day) {
		return ( year > 0 ) && ( 0 < month && month <= 12 ) 
			&& ( 0 < day && day <= getDaysInYearMonth(year, month) );
	}

	public String getDayName(int year, int month, int day) {
		if(!isProperDate(year, month, day))
			return "";
		int reducedDays= getTotalDaysUntil(year, month, day)%dayNames.length;
		return getDayName(reducedDays);
	}

	private String getDayName(int sequence) {
		return dayNames[sequence];
	}

	public int getTotalDaysUntil(int year, int month, int day) {
		if(!isProperDate(year, month, day))
			return 0;
		
		int totalDays= 0;
		for(int i=1;i<year;i++) {
			totalDays += getDaysInYear(i);
		}
		for(int i=1;i<month;i++) {
			totalDays += getDaysInYearMonth(year, i);
		}
		totalDays += day;
		return totalDays;
	}

	public String[] getDayNames() {
		return dayNames;
	}
}


public class CalendarMaker {
	String[] names= {};
	int startIndex= 0;
	private boolean isReady= false;
	private String space= " ";
	
	public void setForm(String[] dayNames, String space) {
		names= dayNames;
		this.space= space;
	}
	public void setMonth(int year, int month, String startName) {
		startIndex= -1;
		for(int i=0;i<names.length;i++) {
			if(startName.equals(names[i])) {
				startIndex= i;
			}				
		}
		if(names != null && startIndex != -1)
			isReady= true;
	}
	public String getResult(int start, int end) {
		if(!isReady()) {
			return "";
		}
		StringWriter sw= new StringWriter();

		sw.write(repeatString(" "+space, startIndex));
		for(int i=start;i<=end;i++) {
			sw.write(String.valueOf(i)+space);
			if((startIndex + i)%names.length==0) {
				sw.write("\n");
			}
		}
		return sw.toString();
	}
	public String getNames(int length) {
		StringWriter sw= new StringWriter();
		for(String name : names) {
			sw.write(name.substring(0, length) + "\t");
		}
		return sw.toString();
	}
	private boolean isReady() {
		return isReady;
	}
	private String repeatString(String string, int repeat) {
		if(repeat == 0) 
			return "";
		return string + repeatString(string, repeat-1);
	}
	
	public static void main(String[] args) throws Exception{
		TimeInfo timeInfo= new TimeInfo();
		CalendarMaker maker= new CalendarMaker();
		int year= 0;
		int month= 0;
		
		System.out.println("input year, month");
		Scanner input= new Scanner(System.in);
		year= input.nextInt();
		month= input.nextInt();
		String startDay= timeInfo.getDayName(year, month, 1);
		maker.setForm(timeInfo.getDayNames(), "\t");
		maker.setMonth(year, month, startDay);
		System.out.println(maker.getNames(4));
		System.out.println(maker.getResult(1, timeInfo.getDaysInYearMonth(year, month)));
	}
}


테스트 코드

public class TestCalendar extends TestCase{
	TimeInfo timeInfo= new TimeInfo();
	CalendarMaker maker= new CalendarMaker();
	
	public void setUp() throws Exception {
		timeInfo= new TimeInfo();
		maker= new CalendarMaker();
	}
	
	public void testDayCount() {
		assertEquals(31, timeInfo.getDaysInMonth(1));
		assertEquals(28, timeInfo.getDaysInMonth(2));
		assertEquals(31, timeInfo.getDaysInMonth(12));
		
		assertEquals(0, timeInfo.getDaysInMonth(0));
		assertEquals(0, timeInfo.getDaysInMonth(13));
	}
	
	public void testActualDaycount() {
		assertEquals(28, timeInfo.getDaysInYearMonth(1999, 2));
		assertEquals(29, timeInfo.getDaysInYearMonth(2004, 2));
		assertEquals(28, timeInfo.getDaysInYearMonth(2100, 2));
		
		assertEquals(0, timeInfo.getDaysInYearMonth(0, 2));
		assertEquals(0, timeInfo.getDaysInYearMonth(2000, 13));
	}
	
	public void testAcutalDayCountInYear() {
		assertEquals(365, timeInfo.getDaysInYear(2003));
		assertEquals(366, timeInfo.getDaysInYear(2000));
		
		assertEquals(0, timeInfo.getDaysInYear(0));
	}
	
	public void testTotalDays() {
		assertEquals(1, timeInfo.getTotalDaysUntil(1,1,1));
		assertEquals(365, timeInfo.getTotalDaysUntil(1,12,31));
		assertEquals(365*2, timeInfo.getTotalDaysUntil(2,12,31));
		assertEquals(365*4+1, timeInfo.getTotalDaysUntil(4,12,31));
	}
	
	public void testDayName() {
		assertEquals("Monday", timeInfo.getDayName(1,1,1));
		assertEquals("Sunday", timeInfo.getDayName(1,1,14));
		assertEquals("Thursday", timeInfo.getDayName(2007,4,26));
		
		assertEquals("", timeInfo.getDayName(2000,2,30));
		assertEquals("", timeInfo.getDayName(2007,4,32));
	}
	public void testInitialMaker() {
		CalendarMaker maker= new CalendarMaker();
		maker.setForm(timeInfo.getDayNames(), " ");
		assertEquals("", maker.getResult(1,4));
		
	}
	public void testMakingCarendar() {
		maker.setForm(timeInfo.getDayNames(), " ");
		maker.setMonth(1,1,"Monday");
		String result= maker.getResult(1,4);
		result.replaceAll("\t", " ");
		assertEquals("  1 2 3 4 ", result);
		assertEquals("  1 2 3 4 5 6 \n7 8 9 10 11 12 13 \n", maker.getResult(1,13));
	}
}

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-05-27 07:09:19
Processing time 0.0959 sec