package com.spun.util.tests; import java.sql.Timestamp; import java.text.DateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import junit.framework.TestCase; import org.approvaltests.Approvals; import org.approvaltests.strings.Printer; import com.spun.util.DateDifference; import com.spun.util.DateUtils; import com.spun.util.parser.TemplateDate; public class DateDifferenceTest extends TestCase { private static final long YEAR_MS = 1000 * 60 * 60 * 24 * 365L; private static final long MONTH_MS = 1000 * 60 * 60 * 24 * 30L; // private static final long WEEK_MS = 1000 * 60 * 60 * 24 * 7L; private static final long DAY_MS = 1000 * 60 * 60 * 24L; private static final long HOUR_MS = 1000 * 60 * 60L; private static final long MINUTE_MS = 1000 * 60L; private static final long SECOND_MS = 1000L; private long getRoundedDifferenceUseCases[][] = { // wanted, round, milli, expected {Calendar.MILLISECOND, Calendar.YEAR, YEAR_MS + 354, 354L}, {Calendar.MILLISECOND, Calendar.YEAR, YEAR_MS - 354, YEAR_MS - 354}, {Calendar.DATE, Calendar.YEAR, YEAR_MS + 3 * DAY_MS, 3L}, {Calendar.DATE, Calendar.YEAR, YEAR_MS - 3 * DAY_MS, (YEAR_MS - 3 * DAY_MS) / DAY_MS}, {Calendar.SECOND, Calendar.HOUR, HOUR_MS + 3 * SECOND_MS, 3L}, {Calendar.SECOND, Calendar.HOUR, HOUR_MS - 3 * SECOND_MS, (HOUR_MS - 3 * SECOND_MS) / SECOND_MS}, {Calendar.SECOND, Calendar.HOUR, HOUR_MS + 3 * MINUTE_MS, 3 * MINUTE_MS / SECOND_MS}, {Calendar.SECOND, Calendar.HOUR, HOUR_MS - 3 * MINUTE_MS, (HOUR_MS - 3 * MINUTE_MS) / SECOND_MS}, {Calendar.SECOND, Calendar.MINUTE, MINUTE_MS + 3 * SECOND_MS, 3L}, {Calendar.SECOND, Calendar.MINUTE, MINUTE_MS - 3 * SECOND_MS, (MINUTE_MS - 3 * SECOND_MS) / SECOND_MS},}; String[] unitsArray = { "Year", "Years", "Month", "Months", "Week", "Weeks", "Day", "Days", "Hour", "Hours", "Min", "Mins", "Sec", "Secs", "Milli", "Millis" }; private GetTimeTextUseCase getTimeTextUseCases[] = { new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, YEAR_MS, "1 Year, 0 Months, 0 Weeks, 0 Days, 0 Hours"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, YEAR_MS + (2 * MONTH_MS), "1 Year, 2 Months, 0 Weeks, 0 Days, 0 Hours"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, YEAR_MS - (2 * MONTH_MS), "10 Months, 0 Weeks, 5 Days, 0 Hours, 0 Mins"), new GetTimeTextUseCase(2, Calendar.YEAR, Calendar.MILLISECOND, "", "ago", unitsArray, YEAR_MS + (2 * MONTH_MS), "1 Year, 2 Months ago"), new GetTimeTextUseCase(5, Calendar.MILLISECOND, Calendar.MILLISECOND, "now", "", unitsArray, YEAR_MS + (2 * MONTH_MS), "36720000000 Millis"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.DATE, "today", "ago", unitsArray, DAY_MS, "1 Day ago"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.DATE, "today", "ago", unitsArray, DAY_MS - 1, "today"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, new GregorianCalendar( 2003, 1, 28), /* 1 = Feb */ new GregorianCalendar(2003, 2, 31), "1 Month, 0 Weeks, 1 Day, 0 Hours, 0 Mins"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, new GregorianCalendar( 2003, 1, 1), new GregorianCalendar(2003, 2, 1), "4 Weeks, 0 Days, 0 Hours, 0 Mins, 0 Secs"), new GetTimeTextUseCase(5, Calendar.YEAR, Calendar.MILLISECOND, "now", "", unitsArray, new GregorianCalendar( 2004, 1, 1), new GregorianCalendar(2004, 2, 1), "4 Weeks, 1 Day, 0 Hours, 0 Mins, 0 Secs"), new GetTimeTextUseCase(5, Calendar.MONTH, Calendar.MILLISECOND, "now", "", unitsArray, new GregorianCalendar(1990, 0, 1), /* 7 * 12 should be 84 */ new GregorianCalendar(1997, 0, 1), "85 Months, 1 Week, 0 Days, 0 Hours, 0 Mins"), new GetTimeTextUseCase(5, Calendar.DATE, Calendar.MILLISECOND, "now", "", unitsArray, new GregorianCalendar( 2004, 3, 3, 10, 0), /* Daylight savings is in month '3' */ new GregorianCalendar(2004, 3, 4, 11, 0), "1 Day, 0 Hours, 0 Mins, 0 Secs, 0 Millis")}; /***********************************************************************/ public void testGetRoundedDifference() { for (int i = 0; i < getRoundedDifferenceUseCases.length; i++) { int wanted = (int) getRoundedDifferenceUseCases[i][0]; int round = (int) getRoundedDifferenceUseCases[i][1]; long milli = getRoundedDifferenceUseCases[i][2]; long expected = getRoundedDifferenceUseCases[i][3]; DateDifference d = new DateDifference(milli); assertEquals("getRoundedDifference(" + wanted + ", " + round + ") on " + milli, expected, d.getRemainingDifference(wanted, round)); } } /***********************************************************************/ public void testFeburaryAndDaylightSavingsTime() throws Exception { if (ignoreIfOutSideUS()) { return; } StringBuffer buffer = new StringBuffer(); DateFormat f = TemplateDate.FORMATS.DATE_SHORT; for (int i = 1; i <= 28; i++) { Timestamp a = DateUtils.parse("2010/02/0" + i); Timestamp b = DateUtils.parse("2010/03/0" + i); DateDifference dif = new DateDifference(a, b); String out = Printer.printLine(f.format(a) + ", " + f.format(b), dif.getStandardTimeText(2, "days", "seconds", null, null)); buffer.append(out); } Approvals.verify(buffer.toString()); } protected boolean ignoreIfOutSideUS() { return !DateUtils.doesDaylightSavingsTimeStartOn("2010/03/14"); } /***********************************************************************/ public void testGetTimeText() { if (ignoreIfOutSideUS()) { return; } for (int i = 0; i < getTimeTextUseCases.length; i++) { int amount = getTimeTextUseCases[i].amount; int maxUnit = getTimeTextUseCases[i].maxUnit; int minUnit = getTimeTextUseCases[i].minUnit; String nowText = getTimeTextUseCases[i].nowText; String agoText = getTimeTextUseCases[i].agoText; String units[] = getTimeTextUseCases[i].units; long milli = getTimeTextUseCases[i].milli; String expected = getTimeTextUseCases[i].expected; DateDifference d = new DateDifference(milli); assertEquals("getTimeText(" + amount + ", " + maxUnit + ", " + minUnit + ", " + nowText + ", " + agoText + ", " + Arrays.toString(units) + ") on " + milli, expected, d.getTimeText(amount, maxUnit, minUnit, nowText, agoText, units)); } } /***********************************************************************/ private class GetTimeTextUseCase { int amount; int maxUnit; int minUnit; String nowText; String agoText; String units[]; long milli; String expected; public GetTimeTextUseCase(int amount, int maxUnit, int minUnit, String nowText, String agoText, String[] units, long milli, String expected) { this.init(amount, maxUnit, minUnit, nowText, agoText, units, milli, expected); } /***********************************************************************/ public GetTimeTextUseCase(int amount, int maxUnit, int minUnit, String nowText, String agoText, String[] units, Calendar date1, Calendar date2, String expected) { long time = date1.getTimeInMillis() - date2.getTimeInMillis(); if (time < 0) { time = -time; } this.init(amount, maxUnit, minUnit, nowText, agoText, units, time, expected); } /***********************************************************************/ private void init(int amount, int maxUnit, int minUnit, String nowText, String agoText, String[] units, long milli, String expected) { this.amount = amount; this.maxUnit = maxUnit; this.minUnit = minUnit; this.nowText = nowText; this.agoText = agoText; this.units = units; this.milli = milli; this.expected = expected; } } /***********************************************************************/ /***********************************************************************/ }