"эта дата - третий четверг месяца?" - Библиотека Java?

У меня есть несколько десятков запросов в очереди, как

'I need this functionality to run on the third Thursday of every month, and the first Wednesday of every other month...'

У меня уже есть функция, которая запускается каждый день, мне просто нужно: isThirdSundayOfMonth(date) немного добавить в конец.

Чем меньше времени я трачу на рассмотрение нюансов григорианского календаря и часовых поясов, тем лучше моя жизнь.

Кто-нибудь знает библиотеку Java, которая упрощает такие вычисления? Нет конфигурации XML или фреймворки или что-нибудь. Просто.Jar и документированный, читаемый API был бы идеальным.

Любая помощь приветствуется.

2 ответа

Полный обзор:

В Java-8 (новый стандарт):

LocalDate input = LocalDate.now(); // using system timezone
int ordinal = 3;
DayOfWeek weekday = DayOfWeek.SUNDAY;

LocalDate adjusted = 
  input.with(TemporalAdjusters.dayOfWeekInMonth(ordinal, weekday));
boolean isThirdSundayInMonth = input.equals(adjusted);

В Joda-Time (популярная сторонняя библиотека):

LocalDate input = new LocalDate(); // using system timezone
int ordinal = 3;
int weekday = DateTimeConstants.SUNDAY;

LocalDate start = new LocalDate(input.getYear(), input.getMonthOfYear(), 1);
LocalDate date = start.withDayOfWeek(weekday);
LocalDate adjusted = (
  date.isBefore(start)) 
  ? date.plusWeeks(ordinal) 
  : date.plusWeeks(ordinal - 1);
boolean isThirdSundayInMonth = input.equals(adjusted);

С помощью java.util.GregorianCalendar (старый стандарт):

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
GregorianCalendar input = new GregorianCalendar();
int ordinal = 3;
int weekday = Calendar.SUNDAY;

GregorianCalendar start =
    new GregorianCalendar(input.get(Calendar.YEAR), input.get(Calendar.MONTH), 1);
int dow = start.get(Calendar.DAY_OF_WEEK); // Sun=1, Mon=2, ...
int delta = (weekday - dow);
if (delta < 0) {
    delta += 7;
}
start.add(Calendar.DAY_OF_MONTH, delta + (ordinal - 1) * 7);
String comp1 = sdf.format(input.getTime());
String comp2 = sdf.format(start.getTime());
boolean isThirdSundayInMonth = comp1.equals(comp2);

Даже с самой уродливой библиотекой решение возможно;-) Я использовал сравнение строк, чтобы избавиться от любых эффектов часового пояса или времени суток, включая миллисекунды. Полевое сравнение, основанное только на годе, месяце и дне месяца, также является хорошей идеей.

Используя Time4J (моя собственная сторонняя библиотека):

PlainDate input = 
  SystemClock.inLocalView().today(); // using system timezone
Weekday weekday = Weekday.SUNDAY;

PlainDate adjusted = 
  input.with(PlainDate.WEEKDAY_IN_MONTH.setToThird(weekday));
boolean isThirdSundayInMonth = input.equals(adjusted);

Каноническая библиотека для всех вещей, связанных с датой и временем, является Joda Time. Принять это и очистить все стандартные классы Java, такие как Date, Calendar, так далее.

Это сделает вашу жизнь намного лучше.

Что касается "Как использовать joda-time, чтобы найти третий четверг месяца", то на этот вопрос уже есть ответ от stackru. Я бы предложил использовать код, который задал вопросник, а затем на вопрос "это уже третий четверг месяца" ответили:

LocalDate today = new LocalDate();
if (today.equals(calcDayOfWeekOfMonth(DateTimeConstants.THURSDAY, 3, today))) {
    // do special third-Thursday processing here
}
Другие вопросы по тегам