I also need this to be a hash of the day of the year, so that March 1, 2000 (a leap year) and March 1, 2001 (not a leap year) hash to the same value.
They key piece of code is this:
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.LENIENT);
Notice this: ResolverStyle.LENIENT
public class DateUtils
{
//This is a hash of the day of the year.
public static int hashDayOfYear(String stringDate)
{
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.LENIENT);
LocalDate date = LocalDate.parse(stringDate, formatter);
int dayOfYear = date.getDayOfYear();
//Leap year stuff
boolean isLeap = Year.isLeap(date.getYear());
//February 28th is the 59th day of the year.
if( isLeap )
{
if(dayOfYear == 60)
{
//This allows for exact matching of dates but interfears with range matching
dayOfYear = 366;
}
else if (dayOfYear > 59)
{
dayOfYear--;
}
}
return dayOfYear;
}
}
public class DateUtilsTest
{
@Test
public void testOne()
{
//Feb 28 of a leap year
String date = "2000-02-28"
int dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 59;
//Feb 29 of leap year maps to 366
date = "2000-02-29"
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 366;
//Feb 29, but not leap year, needs to be lenient and map to March 1
date = "2001-02-29"
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 60;
//Feb 30 of a leap year, needs to be lenient and map to March 1
date = "2000-2-30";
dayOfYear = DateUtils.hashDayOfYear(date);
assert dayOfYear == 60;
}
}