package kr.kangwoo.util;

import static org.junit.Assert.*;
import static kr.kangwoo.util.DateUtils.*;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import junit.framework.Assert;
import kr.kangwoo.util.date.DatePatternToken;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class DateUtilsTest {

	@Before
	public void setUp() throws Exception {
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testToCalendar() {
		long millis = System.currentTimeMillis();
		Date date = new Date(millis);
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		Assert.assertEquals(toCalendar(date), cal);
	}

	@Test
	public void testGetCurrentDate() {
		Date date = getCurrentDate();
		Calendar cal = Calendar.getInstance();;
		cal.setTime(date);
		Assert.assertEquals(cal.get(Calendar.HOUR_OF_DAY), 0);
		Assert.assertEquals(cal.get(Calendar.MINUTE), 0);
		Assert.assertEquals(cal.get(Calendar.SECOND), 0);
		Assert.assertEquals(cal.get(Calendar.MILLISECOND), 0);
	}

	@Test
	public void testGetCurrentTime() {
		// Å×½ºÆ® ¹æµµ°¡ ¾ø´Ù...
	}

	@Test
	public void testToDateIntIntIntIntIntInt() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toDate(year, month, day, hour, minute, second), calendar.getTime());
	}

	@Test
	public void testToDateIntIntIntIntInt() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toDate(year, month, day, hour, minute, 0), calendar.getTime());
	}

	@Test
	public void testToDateIntIntInt() {
		int year = 1978;
		int month = 7;
		int day = 19;

		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, 0, 0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toDate(year, month, day, 0, 0, 0), calendar.getTime());
	}

	@Test
	public void testToDateStringStringDate() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toDate("1978-07-19 11:12:13.000", "yyyy-MM-dd HH:mm:ss.SSS", null), calendar.getTime());
		
		Date date = new Date();
		Assert.assertEquals(toDate("1978-07-19 11:12:13.000", "HaHaHa MM-dd", date), date);
	}

	@Test
	public void testToDateStringString() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		try {
			Assert.assertEquals(toDate("1978-07-19 11:12:13.000", "yyyy-MM-dd HH:mm:ss.SSS"), calendar.getTime());
		} catch (ParseException e) {
			fail(e.getMessage());
		}
	}

	@Test
	public void testToDateString() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toDate("1978-07-19 11:12:13.000"), calendar.getTime());
	}

	@Test
	public void testToNumber() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(toNumber(calendar.getTime(), "yyyy"), 1978);
		Assert.assertEquals(toNumber(calendar.getTime(), "MM"), 7);
		Assert.assertEquals(toNumber(calendar.getTime(), "dd"), 19);
		Assert.assertEquals(toNumber(calendar.getTime(), "HH"), 11);
		Assert.assertEquals(toNumber(calendar.getTime(), "mm"), 12);
		Assert.assertEquals(toNumber(calendar.getTime(), "ss"), 13);
		Assert.assertEquals(toNumber(calendar.getTime(), "SSS"), 0);
	}

	@Test
	public void testToStringDateString() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "yyyy"), "1978");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "MM"), "07");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "dd"), "19");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "HH"), "11");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "mm"), "12");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "ss"), "13");
		Assert.assertEquals(DateUtils.toString(calendar.getTime(), "SSS"), "000");
	}

	@Test
	public void testGet() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(get(calendar.getTime(), Calendar.YEAR), 1978);
		Assert.assertEquals(get(calendar.getTime(), Calendar.MONTH), 7 - 1);
	}

	@Test
	public void testGetYear() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getYear(calendar.getTime()), 1978);
	}

	@Test
	public void testGetMonth() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getMonth(calendar.getTime()), month);
	}

	@Test
	public void testGetWeek() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getWeek(calendar.getTime()), 29);
	}

	@Test
	public void testGetDay() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getDay(calendar.getTime()), 19);
	}

	@Test
	public void testGetHour() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getHour(calendar.getTime()), 11);
	}

	@Test
	public void testGetMinute() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getMinute(calendar.getTime()), 12);
	}

	@Test
	public void testGetSecond() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getSecond(calendar.getTime()), 13);
	}

	@Test
	public void testGetMillisecond() {
		int year = 1978;
		int month = 7;
		int day = 19;
		int hour = 11;
		int minute = 12;
		int second = 13;
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, minute, second);
		calendar.set(Calendar.MILLISECOND, 0);
		
		Assert.assertEquals(getMillisecond(calendar.getTime()), 0);
	}

	@Test
	public void testSet() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.YEAR;
		int value = 2010;
		cal2.set(field, value);
		
		Assert.assertEquals(set(cal1.getTime(), field, value), cal2.getTime());
		
	}
	
	@Test
	public void testSetYear() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.YEAR;
		int value = 1978;
		cal2.set(field, value);
		
		Assert.assertEquals(setYear(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetMonth() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.MONTH;
		int value = 7;
		cal2.set(field, value - 1);
		
		Assert.assertEquals(setMonth(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetDay() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.DAY_OF_MONTH;
		int value = 19;
		cal2.set(field, value);
		
		Assert.assertEquals(setDay(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetHour() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.HOUR_OF_DAY;
		int value = 19;
		cal2.set(field, value);
		
		Assert.assertEquals(setHour(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetMinute() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.MINUTE;
		int value = 59;
		cal2.set(field, value);
		
		Assert.assertEquals(setMinute(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetSecond() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.SECOND;
		int value = 57;
		cal2.set(field, value);
		
		Assert.assertEquals(setSecond(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetMillisecond() {
		Calendar cal1 = Calendar.getInstance();
		cal1.clear();
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		int field = Calendar.MILLISECOND;
		int value = 333;
		cal2.set(field, value);
		
		Assert.assertEquals(setMillisecond(cal1.getTime(), value), cal2.getTime());
	}

	@Test
	public void testSetTimeDateIntIntIntInt() {
		int hour = 13;
		int minute = 11;
		int second = 22;
		int millisecond = 999;
		Date date = setTime(new Date(), hour, minute, second, millisecond);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Assert.assertEquals(cal.get(Calendar.HOUR_OF_DAY), hour);
		Assert.assertEquals(cal.get(Calendar.MINUTE), minute);
		Assert.assertEquals(cal.get(Calendar.SECOND), second);
		Assert.assertEquals(cal.get(Calendar.MILLISECOND), millisecond);	
	}

	@Test
	public void testSetTimeDateIntIntInt() {
		int hour = 13;
		int minute = 11;
		int second = 22;
		Date date = setTime(new Date(), hour, minute, second);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Assert.assertEquals(cal.get(Calendar.HOUR_OF_DAY), hour);
		Assert.assertEquals(cal.get(Calendar.MINUTE), minute);
		Assert.assertEquals(cal.get(Calendar.SECOND), second);	
	}

	@Test
	public void testAdd() {
		Date date1 = toDate("1978-07-19");
		Date date2 = toDate("1979-07-19");
		
		Assert.assertEquals(add(date1, Calendar.YEAR, 1), date2);
	}

	@Test
	public void testAddYears() {
		Date date1 = toDate("1978-07-19");
		Date date2 = toDate("1979-07-19");
		
		Assert.assertEquals(addYears(date1, 1), date2);
	}

	@Test
	public void testAddMonths() {
		Date date1 = toDate("1978-07-19");
		Date date2 = toDate("1979-01-19");
		
		Assert.assertEquals(addMonths(date1, 6), date2);
	}

	@Test
	public void testAddDays() {
		Date date1 = toDate("1978-07-19");
		Date date2 = toDate("1978-08-18");
		
		Assert.assertEquals(addDays(date1, 30), date2);
	}

	@Test
	public void testAddHours() {
		Date date1 = toDate("1978-07-19 19:00:00");
		Date date2 = toDate("1978-07-20 01:00:00");
		
		Assert.assertEquals(addHours(date1, 6), date2);
	}

	@Test
	public void testAddMinutes() {
		Date date1 = toDate("1978-07-19 23:51:00");
		Date date2 = toDate("1978-07-20 00:00:00");
		
		Assert.assertEquals(addMinutes(date1, 9), date2);
	}

	@Test
	public void testAddSeconds() {
		Date date1 = toDate("1978-07-19 23:59:59");
		Date date2 = toDate("1978-07-20 00:00:00");
		
		Assert.assertEquals(addSeconds(date1, 1), date2);
	}

	@Test
	public void testAddMilliseconds() {
		Date date1 = toDate("1978-07-19 23:59:59.001");
		Date date2 = toDate("1978-07-20 00:00:00");
		
		Assert.assertEquals(addMilliseconds(date1, 999), date2);
	}

	@Test
	public void testGetNextDateDateInt() {
		Date date1 = toDate("1978-07-19");
		
		Assert.assertEquals(getNextDate(date1, Calendar.SUNDAY), toDate("1978-07-23"));
		Assert.assertEquals(getNextDate(date1, Calendar.MONDAY), toDate("1978-07-24"));
		Assert.assertEquals(getNextDate(date1, Calendar.TUESDAY), toDate("1978-07-25"));
		Assert.assertEquals(getNextDate(date1, Calendar.WEDNESDAY), toDate("1978-07-26"));
		Assert.assertEquals(getNextDate(date1, Calendar.THURSDAY), toDate("1978-07-27"));
		Assert.assertEquals(getNextDate(date1, Calendar.FRIDAY), toDate("1978-07-28"));
		Assert.assertEquals(getNextDate(date1, Calendar.SATURDAY), toDate("1978-07-29"));
	}

	@Test
	public void testGetNextDateDateIntBoolean() {
		Date date1 = toDate("1978-07-19 11:25:34");
		
		Assert.assertEquals(getNextDate(date1, Calendar.SUNDAY, true), toDate("1978-07-23"));
		Assert.assertEquals(getNextDate(date1, Calendar.MONDAY, true), toDate("1978-07-24"));
		Assert.assertEquals(getNextDate(date1, Calendar.TUESDAY, true), toDate("1978-07-25"));
		Assert.assertEquals(getNextDate(date1, Calendar.WEDNESDAY, true), toDate("1978-07-26"));
		Assert.assertEquals(getNextDate(date1, Calendar.THURSDAY, true), toDate("1978-07-27"));
		Assert.assertEquals(getNextDate(date1, Calendar.FRIDAY, true), toDate("1978-07-28"));
		Assert.assertEquals(getNextDate(date1, Calendar.SATURDAY, true), toDate("1978-07-29"));
		
		Assert.assertEquals(getNextDate(date1, Calendar.SUNDAY, false), toDate("1978-07-23 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.MONDAY, false), toDate("1978-07-24 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.TUESDAY, false), toDate("1978-07-25 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.WEDNESDAY, false), toDate("1978-07-26 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.THURSDAY, false), toDate("1978-07-27 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.FRIDAY, false), toDate("1978-07-28 11:25:34"));
		Assert.assertEquals(getNextDate(date1, Calendar.SATURDAY, false), toDate("1978-07-29 11:25:34"));
	}

	@Test
	public void testGetLastDateDate() {
		Date date1 = toDate("1978-07-19 11:25:34");
		
		Assert.assertEquals(getLastDate(date1), toDate("1978-07-31 11:25:34"));
	}

	@Test
	public void testGetLastDateDateBoolean() {
		Date date1 = toDate("1978-07-19 11:25:34");
		
		Assert.assertEquals(getLastDate(date1, true), toDate("1978-07-31 00:00:00"));
		Assert.assertEquals(getLastDate(date1, false), toDate("1978-07-31 11:25:34"));
	}

	@Test
	public void testIsSameDayCalendarCalendar() {
		Calendar cal1 = toCalendar(toDate("1978-07-19 11:25:34"));
		Calendar cal2 = toCalendar(toDate("1978-07-19 23:11:13"));
		
		Assert.assertTrue(isSameDay(cal1, cal2));
	}

	@Test
	public void testIsSameDayDateDate() {
		Assert.assertTrue(isSameDay(toDate("1978-07-19 11:25:34"), toDate("1978-07-19 23:11:13")));
	}

	@Test
	public void testGetBetween() {
		Assert.assertEquals(getBetween(toDate("2008-11-11 23:59"), toDate("2008-11-12 23:58")), 86340000);
		Assert.assertEquals(getBetween(toDate("2008-11-11 23:59"), toDate("2008-11-12 23:59")), 86400000);
		Assert.assertEquals(getBetween(null, toDate("2008-11-12 23:59")), 0);
		Assert.assertEquals(getBetween(toDate("2008-11-11 23:59"), null), 0);
	}

	@Test
	public void testGetDaysBetween() {
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-11"), toDate("2008-11-13")), 2);
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-11"), toDate("2008-11-11")), 0);
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-12"), toDate("2008-11-11")), -1);
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-11 23:59"), toDate("2008-11-12 23:58")), 0);
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-11 23:59"), toDate("2008-11-12 23:59")), 1);
		 Assert.assertEquals(getDaysBetween(null, toDate("2008-11-12 23:59")), 0);
		 Assert.assertEquals(getDaysBetween(toDate("2008-11-11 23:59"), null), 0);
	}

	@Test
	public void testToStringLongString() {
		 Assert.assertEquals(DateUtils.toString(100000, "dd HH:mm:ss.SSS"), "00 00:01:40.000");
	}

	@Test
	public void testToStringLongStringBoolean() {
		Assert.assertEquals(DateUtils.toString(100000, "dd HH:mm:ss.SSS", true), "00 00:01:40.000");
		Assert.assertEquals(DateUtils.toString(100000, "dd HH:mm:ss.SSS", false), "0 0:1:40.0");
	}

	@Test
	public void testToStringLongLongString() {
		 Assert.assertEquals(DateUtils.toString(269644500000l, 1100125141004l, "yyyy-MM-dd HH:mm:ss.SSS"), "0026-03-23 01:04:01.004");
		 Assert.assertEquals(DateUtils.toString(269644500000l, 1100125141004l, "MM-dd HH:mm:ss.SSS"), "315-23 01:04:01.004");
	}

	@Test
	public void testToStringLongLongStringBoolean() {
		 Assert.assertEquals(DateUtils.toString(269644500000l, 1100125141004l, "yyyy-MM-dd HH:mm:ss.SSS", true), "0026-03-23 01:04:01.004");
		 Assert.assertEquals(DateUtils.toString(269644500000l, 1100125141004l, "yyyy-MM-dd HH:mm:ss.SSS", false), "26-3-23 1:4:1.4");
		 Assert.assertEquals(DateUtils.toString(269644500000l, 1100125141004l, "MM-dd HH:mm:ss.SSS", true), "315-23 01:04:01.004");
	}

	@Test
	public void testToStringDateDateString() {
		 Assert.assertEquals(DateUtils.toString(toDate("1978-07-19 06:15:00.000"), toDate("2004-11-11 07:19:01.004"), "yyyy-MM-dd HH:mm:ss.SSS"), "0026-03-23 01:04:01.004");
		 Assert.assertEquals(DateUtils.toString(toDate("1978-07-19 06:15:00.000"), toDate("2004-11-11 07:19:01.004"), "MM-dd HH:mm:ss.SSS"), "315-23 01:04:01.004");
	}

	@Test
	public void testToStringDateDateStringBoolean() {
		 Assert.assertEquals(DateUtils.toString(toDate("1978-07-19 06:15:00.000"), toDate("2004-11-11 07:19:01.004"), "yyyy-MM-dd HH:mm:ss.SSS", true), "0026-03-23 01:04:01.004");
		 Assert.assertEquals(DateUtils.toString(toDate("1978-07-19 06:15:00.000"), toDate("2004-11-11 07:19:01.004"), "yyyy-MM-dd HH:mm:ss.SSS", false), "26-3-23 1:4:1.4");
		 Assert.assertEquals(DateUtils.toString(toDate("1978-07-19 06:15:00.000"), toDate("2004-11-11 07:19:01.004"), "MM-dd HH:mm:ss.SSS", true), "315-23 01:04:01.004");
	}

	@Test
	public void testFormat() {
		int years = 1978;
		int months = 7;
		int days = 19;
		int hours = 11;
		int minutes = 12;
		int seconds = 13;
		int milliseconds = 555;
		Assert.assertEquals(DateUtils.format(DatePatternToken.getTokens("yyyy-MM-dd HH:mm:ss"), years, months, days, hours, minutes, seconds, milliseconds, true), "1978-07-19 11:12:13");
		Assert.assertEquals(DateUtils.format(DatePatternToken.getTokens("yyyy-MM-dd HH:mm:ss"), years, months, days, hours, minutes, seconds, milliseconds, false), "1978-7-19 11:12:13");
	}

}

