I need to implement a mechanism in Java, which alternates a statement each week, eg. in week one it sets a variable to 10, in week two it sets it to 15 and in week 3 it sets it to 10 again.
This should work for every year. I now tried archeiving this by getting the week number and checking if it is even.(date.getWeekNumber() % 2 == 0
).
The problem here is that the year 2014 does have only 52 weeks, while the year 2015 and 2016 do have 53 weeks. This would lead to having 53 % 2 = 1 and on the following week 1 % 1 = 1, which in my case would set the wrong variables.
Does anyone have a clue how to improve this?
You'd need to know the number of weeks in each year, so you could work out whether your condition was enabled for odd weeks or even weeks. You can't just work out whether this year or last year has an even or odd number of weeks in the year, as it's basically cumulative.
If you only need this for a limited range of dates (e.g. 2000 to 2100) then you could just calculate a table. If you need it over a very wide range of dates, you could build up a table of 400 years and take advantage of everything cycling every 400 years.
Example of the simpler case, using the java.time
API:
For example:
private static final int MIN_YEAR_INCLUSIVE = 2000;
private static final int MAX_YEAR_EXCLUSIVE = 2100;
private static final boolean[] ENABLED_FOR_ODD_WEEKS =
buildTable(MIN_YEAR_INCLUSIVE, MAX_YEAR_EXCLUSIVE);
private static final boolean[] buildTable(int minYear, int maxYear) {
boolean[] table = new boolean[maxYear - minYear];
boolean current = true;
for (int year = minYear; year < maxYear; year++) {
table[year - minYear] = current;
Year accessor = Year.of(year);
int weeksInYear = IsoFields
.WEEK_OF_WEEK_BASED_YEAR
.rangeRefinedBy(accessor)
.getMaximum();
if (weeksInYear == 53) {
current = !current;
}
}
}
public boolean isEnabled(LocalDate date) {
int year = date.getYear();
if (year < MIN_YEAR_INCLUSIVE || year >= MAX_YEAR_EXCLUSIVE) {
throw new IllegalArgumentException("Invalid year: " + year);
}
int weekOfWeekYear = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
boolean oddWeek = weekOfWeekYear % 2 == 1;
return oddWeek == ENABLED_FOR_ODD_WEEKS[year - MIN_YEAR_INCLUSIVE];
}
See more on this question at Stackoverflow