package core.util;

import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.JUnitCore;

public class TestDateUtil {

	/**
	 * main
	 * @param args arguments
	 */
	public static void main(final String... args) {
		JUnitCore.main(TestDateUtil.class.getName());
	}

	@Test
	public void 絶対日変換０基準() {
		String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
		Assert.assertEquals(date, DateUtil.toAbsolute("本日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("今日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("今週"));
		Assert.assertEquals(date, DateUtil.toAbsolute("今月"));
		Assert.assertEquals(date, DateUtil.toAbsolute("今年"));
	}

	@Test
	public void 絶対日変換プラス１プラス２基準() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("翌日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("後日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("明日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("次日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("来日"));

		cal.add(Calendar.DATE, 1);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("翌々日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("明後日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("二日後"));
		Assert.assertEquals(date, DateUtil.toAbsolute("２日後"));
		Assert.assertEquals(date, DateUtil.toAbsolute("2日後"));
		Assert.assertEquals(date, DateUtil.toAbsolute("再来日"));
	}

	@Test
	public void 絶対日変換マイナス１マイナス２変換() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("先日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("前日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("昨日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("去日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("一日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("１日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("1日前"));

		cal.add(Calendar.DATE, -1);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("二日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("２日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("2日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("一昨日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("１昨日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("1昨日"));
		Assert.assertEquals(date, DateUtil.toAbsolute("先々日"));
	}

	@Test
	public void 絶対日変換週おわり() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, 7 - cal.get(Calendar.DAY_OF_WEEK));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("週末"));

		cal = Calendar.getInstance();
		cal.add(Calendar.WEEK_OF_MONTH, -1);
		cal.add(Calendar.DATE, 7 - cal.get(Calendar.DAY_OF_WEEK));
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("先週末"));

		cal.add(Calendar.WEEK_OF_MONTH, -2);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("三週間前末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("３週間前末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("3週間前末"));
	}

	@Test
	public void 絶対日変換月おわり() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, -1);
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("先月末"));

		Assert.assertEquals(date, DateUtil.toAbsolute("先月終わり"));
	}

	@Test
	public void 絶対日変換年おわり() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.YEAR, -1);
		cal.set(Calendar.MONTH, 12);
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("去年末"));

		cal.add(Calendar.YEAR, -1);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("一昨年末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("昨昨年末"));

		cal.add(Calendar.YEAR, 3);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("来年末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("翌年終"));
	}

	@Test
	public void 絶対日変換週はじめ() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1 * (cal.get(Calendar.DAY_OF_WEEK) - 1));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("週初め"));

		cal = Calendar.getInstance();
		cal.add(Calendar.WEEK_OF_MONTH, -1);
		cal.add(Calendar.DATE, -1 * (cal.get(Calendar.DAY_OF_WEEK) - 1));
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("先週初"));

		cal.add(Calendar.WEEK_OF_MONTH, -2);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("三週間前始"));
		Assert.assertEquals(date, DateUtil.toAbsolute("３週間前始"));
		Assert.assertEquals(date, DateUtil.toAbsolute("3週間前始"));
	}

	@Test
	public void 絶対日変換月はじめ() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, -1);
		cal.set(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("先月初"));
	}

	@Test
	public void 絶対日変換年はじめ() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.YEAR, -1);
		cal.set(Calendar.MONTH, 1);
		cal.set(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("去年始"));

		cal.add(Calendar.YEAR, -1);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("一昨年始"));

		cal.add(Calendar.YEAR, -1);
		date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("去昨昨年初"));
	}

	@Test
	public void 絶対日変換n日前() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -3);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("三日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("３日前"));
		Assert.assertEquals(date, DateUtil.toAbsolute("3日前"));
	}

	@Test
	public void 絶対日変換０基準クオータはじめ() {
		Calendar cal = Calendar.getInstance();
		int month = cal.get(Calendar.MONTH);
		if (0 <= month && month <= 2) {
			cal.set(Calendar.MONTH, 0);
		} else if (3 <= month && month <= 5) {
			cal.set(Calendar.MONTH, 3);
		} else if (6 <= month && month <= 8) {
			cal.set(Calendar.MONTH, 6);
		} else {
			cal.set(Calendar.MONTH, 9);
		}
		cal.set(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("当Ｑ初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当ｑ初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当Q初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当q初"));
	}

	@Test
	public void 絶対日変換０基準クオータおわり() {
		Calendar cal = Calendar.getInstance();
		int month = cal.get(Calendar.MONTH);
		if (0 <= month && month <= 2) {
			cal.set(Calendar.MONTH, 2);
		} else if (3 <= month && month <= 5) {
			cal.set(Calendar.MONTH, 5);
		} else if (6 <= month && month <= 8) {
			cal.set(Calendar.MONTH, 8);
		} else {
			cal.set(Calendar.MONTH, 11);
		}
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("当Ｑ末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当ｑ末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当Q末"));
		Assert.assertEquals(date, DateUtil.toAbsolute("当q末"));
	}

	@Test
	public void 絶対日変換四半期はじめ() {
		Calendar cal = Calendar.getInstance();
		int month = cal.get(Calendar.MONTH);
		if (3 <= month && month <= 8) {
			cal.set(Calendar.MONTH, 3);
		} else if (9 <= month && month <= 11) {
			cal.set(Calendar.MONTH, 9);
		} else if (month <= 2) {
			cal.set(Calendar.MONTH, 0);
			cal.add(Calendar.MONTH, -3);
		}
		cal.set(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("当期初"));
	}

	@Test
	public void 絶対日変換四半期おわり() {
		Calendar cal = Calendar.getInstance();
		int month = cal.get(Calendar.MONTH);
		if (3 <= month && month <= 8) {
			cal.set(Calendar.MONTH, 8);
		} else if (9 <= month && month <= 11) {
			cal.set(Calendar.MONTH, 11);
			cal.add(Calendar.MONTH, 3);
		} else if (month <= 2) {
			cal.set(Calendar.MONTH, 2);
		}
		cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("当期末"));
	}

	@Test
	public void 絶対日変換クオータ前はじめ() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, -9);
		int month = cal.get(Calendar.MONTH);
		if (0 <= month && month <= 2) {
			cal.set(Calendar.MONTH, 0);
		} else if (3 <= month && month <= 5) {
			cal.set(Calendar.MONTH, 3);
		} else if (6 <= month && month <= 8) {
			cal.set(Calendar.MONTH, 6);
		} else {
			cal.set(Calendar.MONTH, 9);
		}
		cal.set(Calendar.DATE, 1);
		String date = new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
		Assert.assertEquals(date, DateUtil.toAbsolute("３Ｑ前初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("３ｑ前初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("3Q前初"));
		Assert.assertEquals(date, DateUtil.toAbsolute("3q前初"));
	}

	@Test
	public void 絶対日変換変換不可全角文字() {
		Assert.assertEquals(new SimpleDateFormat("yyyyMMdd").format(new Date()), DateUtil.toAbsolute("あ"));
	}

	@Test
	public void 絶対日変換変換不可文字() {
		Assert.assertEquals(null, DateUtil.parseDate("20101233", "yyyyMMdd"));
		Assert.assertEquals(null, DateUtil.parseDate("201a1233", "yyyyMMdd"));
	}

	@Test
	public void 絶対日変換入力絶対日の場合() {
		Assert.assertEquals("20100102", DateUtil.normalizeDate("201012"));
		Assert.assertEquals("20100131", DateUtil.normalizeDate("2010131"));
		Assert.assertEquals("20101203", DateUtil.normalizeDate("2010123"));
		Assert.assertEquals("20100123", DateUtil.normalizeDate("20101/23"));
		Assert.assertEquals("20101203", DateUtil.normalizeDate("201012/3"));
		Assert.assertEquals("20101203", DateUtil.normalizeDate("20101/2/3"));
		Assert.assertEquals("2010/11/", DateUtil.normalizeDate("2010/11/"));
		Assert.assertEquals("20100101", DateUtil.normalizeDate("2010/1/1"));
	}

	@Test
	public void 日付オブジェクト変換() {
		Date date = new Date();
		Time time = DateUtil.toTime(date);
		java.sql.Date day = DateUtil.toDate(date);
		Assert.assertEquals(date, DateUtil.toDateObject(DateUtil.format(date, DateUtil.FORMAT_DATE_TIME), Timestamp.class));
		Assert.assertEquals(date, DateUtil.toDateObject(DateUtil.format(date, DateUtil.FORMAT_DATE_TIME), Date.class));
		Assert.assertEquals(day, DateUtil.toDateObject(DateUtil.format(day, DateUtil.FORMAT_DATE), java.sql.Date.class));
		Assert.assertEquals(time, DateUtil.toDateObject(DateUtil.format(time, "HHmmssSSS"), Time.class));
	}
}
