Time is always a thorn in the side of developers.
In my latest project I needed to know the number of hours in a day and I could find no easy method on existing classes to determine if the day was a clock change day. I thought the great
Joda date time classes would have helped but I could not find the one I needed so I wrote this.
public enum ClockChangeInfo {
LONG_DAY(90000000, 25), SHORT_DAY(82800000, 23), NORMAL_DAY(86400000, 24), INDETERMINATE(0, 0);
private int mMsecs;
private int mHrs;
private static final Map<Integer, ClockChangeInfo> MSEC = new HashMap<Integer, ClockChangeInfo>();
static {
for (ClockChangeInfo cci : values()) {
MSEC.put(new Integer(cci.mMsecs), cci);
}
}
ClockChangeInfo(int aMsecs, int aHrs) {
mMsecs = aMsecs;
mHrs = aHrs;
}
public int getHrs(ClockChangeInfo aCci) {
return aCci.mHrs;
}
public static ClockChangeInfo getDayType(DateMidnight dateToCheck) {
DateMidnight nextDay = dateToCheck.plusDays(1);
//this is a safe convert as it is only for day(n) - day(n-1)
Integer millis = (int)(nextDay.getMillis() - dateToCheck.getMillis());
ClockChangeInfo cci = MSEC.get(millis);
if (cci == null) {
return INDETERMINATE;
}
return cci;
}
}
public class ClockChangeUtil {
public static ClockChangeInfo getDayType(DateMidnight dateToCheck) {
return ClockChangeInfo.getDayType((dateToCheck));
}
public static int getNumHoursInDay(DateMidnight dateToCheck) {
ClockChangeInfo dayType = ClockChangeUtil.getDayType(dateToCheck);
return dayType.getHrs(dayType);
}
public static int getNumHalfHoursINMonthSoFar(DateMidnight dateToCheck) {
int numHours = 0;
int day = dateToCheck.getDayOfMonth();
if (day == 1) {
return 0;
}
DateMidnight dm = dateToCheck.minusDays(1);
do {
numHours += getNumHoursInDay(dm);
dm = dm.minusDays(1);
day--;
} while (day > 1);
return numHours * 2;
}
}
and some test methods for it. NB these are UK based.
public class ClockChangeUtilUnitTest
{
@Test
public void test_isLongDay() throws Exception
{
DateMidnight dm28 = new DateMidnight(2011, 10, 28);
DateMidnight dm29 = new DateMidnight(2011, 10, 29);
DateMidnight dm30 = new DateMidnight(2011, 10, 30);
DateMidnight dm31 = new DateMidnight(2011, 10, 31);
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm28));
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm29));
assertEquals(ClockChangeInfo.LONG_DAY, ClockChangeUtil.getDayType(dm30));
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm31));
}
@Test
public void test_isShortDay() throws Exception
{
DateMidnight dm26 = new DateMidnight(2011, 3, 26);
DateMidnight dm27 = new DateMidnight(2011, 3, 27);
DateMidnight dm28 = new DateMidnight(2011, 3, 28);
DateMidnight dm29 = new DateMidnight(2011, 3, 29);
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm26));
assertEquals(ClockChangeInfo.SHORT_DAY, ClockChangeUtil.getDayType(dm27));
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm28));
assertEquals(ClockChangeInfo.NORMAL_DAY, ClockChangeUtil.getDayType(dm29));
}
@Test
public void testClockChange() throws Exception
{
long millisInANormalDay = 24 * 60 * 60 * 1000;
long millisInALongDay = 25 * 60 * 60 * 1000;
DateMidnight dm28 = new DateMidnight(2011, 10, 28);
DateMidnight dm29 = new DateMidnight(2011, 10, 29);
DateMidnight dm30 = new DateMidnight(2011, 10, 30);
DateMidnight dm31 = new DateMidnight(2011, 10, 31);
assertEquals(millisInANormalDay, dm29.getMillis() - dm28.getMillis());
assertEquals(millisInANormalDay, dm30.getMillis() - dm29.getMillis());
assertEquals(millisInALongDay, dm31.getMillis() - dm30.getMillis());
DateTime dt28 = new DateTime(dm28);
DateTime dt29 = new DateTime(dm29);
DateTime dt30 = new DateTime(dm30);
DateTime dt31 = new DateTime(dm31);
assertEquals(millisInANormalDay, dt29.getMillis() - dt28.getMillis());
assertEquals(millisInANormalDay, dt30.getMillis() - dt29.getMillis());
assertEquals(millisInALongDay, dt31.getMillis() - dt30.getMillis());
assertTrue(dt28.getZone().equals(dt29.getZone()));
assertTrue(dt28.getZone().equals(dt30.getZone()));
assertTrue(dt28.getZone().equals(dt31.getZone()));
}
@Test
public void test_getNumHoursInDay() throws Exception
{
DateMidnight dm26 = new DateMidnight(2011, 3, 26);
DateMidnight dm27 = new DateMidnight(2011, 3, 27);
DateMidnight dm28 = new DateMidnight(2011, 3, 28);
DateMidnight dm29 = new DateMidnight(2011, 3, 29);
assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm26));
assertEquals(23, ClockChangeUtil.getNumHoursInDay(dm27));
assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm28));
assertEquals(24, ClockChangeUtil.getNumHoursInDay(dm29));
}
}