Праздники - есть ли реализация java?


Я хотел бы знать, есть ли там jar-файл, который может сделать следующее:

DateMidnight dateInQuestion = new DateMidnight(12,12,2000);
DateChecker.isNationalHoliday(dateInQuestion, Locale.ITALY);

если нет, то почему? Конечно, есть много правил, основанных на праздники в 99% случаев.

прямо сейчас мы поддерживаем таблицу в нашей базе данных, со странами + у нас есть некоторые реализации, когда дело доходит до праздников, которые не на ту же дату каждый год. Мы должны добавить к нашей реализации для каждой новой страны мы получаем новые клиенты.

Не могли бы мы сделать это проще?

(если нет такой вещи в сфере java, могу ли я перенести ее с какого-либо другого языка?)

8 53

8 ответов:

насколько мне известно, в Java нет ничего надежного. Это также имеет смысл, такая информация, а именно чрезвычайно чувствительна к изменениям. Жесткое кодирование это сделает ваш код потенциально сломанным на каждом обновлении Java, что может привести к большому количеству проблем с обслуживанием и совместимостью. В настоящее время на самом высоком уровне часовые пояса жестко закодированы/поддерживаются в Java SE и даже в одиночку, что уже привело к много ошибок.

скорее используйте для этого общедоступный веб-сервис. Например. http://www.bank-holidays.com

этот сайт информирует вас обо всех днях, когда банки (а также фондовая биржа и школьные каникулы в ряде стран) закрыты из-за религиозных или общественных мероприятий. Основные события (выборы, объявленные забастовки, ярмарки, фестивали, спортивные мероприятия...) также перечислены.

наш бесплатный сервис позволяет просматривать текущий календарный год (только просмотр). За 2 евро / Страна / год, наш платный сервис (нажмите на значок кредитной карты) дает вам доступ к календарным годам 2000-2070.

и написать Java-оболочку вокруг этого. Или ищите существующие Java API, которые, в свою очередь, уже поддерживаются веб-сервисом.

Я написал Jollyday API и мне интересно знать, что так "грубо" об этом. Как я могу его улучшить? Было бы здорово услышать от вас. Отправьте мне письмо по адресу sdiedrichsen@yahoo.de если хочешь.

кстати. Jollyday используется именно так, как просит его спрашивающий. Пожалуйста, посмотрите сами.

Ура, Свен

P. S.: Я нашел бесплатный веб-сервис от Ульриха Хильгер, который предоставляет подробную праздник информация. Смотреть api.daybase.eu

Я также написал Java-обертку вокруг Ruby Holidays Gem (. Он доступен на Github:https://github.com/gdepourtales/holidays. он работает аналогично Jollyday (http://sourceforge.net/projects/jollyday/).

Я нашел это интересно:

поставщик услуг RESTful -праздник API

для проектов узлов - node-holidayapi

Я знаю, что это не относится к вопросу, заданному для реализации Java. Но если ваш проект спокойный (как и большинство проектов в настоящее время), то это даст вам место для начала. ;)

мой поиск привел к двум результатам (в дополнение к тому, что я перечислил в комментариях). Во-первых, Holiday Client API, Кажется, мертвый проект. Второй,Jollyday, выглядит как очень грубая, но активная, незавершенная работа.

Как почему нет хорошей библиотеки, я с Томом. Я подозреваю, что ваша посылка "наверняка есть много правильно основанных правил для праздников в 99% случаев" неверна.

Я думаю, что вы должны будете сделать работу самостоятельно.

национальные праздники определяются, ну, наций. Они могут меняться, и по определению не являются универсальными, и поэтому не могут быть захвачены каким-либо алгоритмом.

единственный способ отслеживать их-это поддерживать их на национальной основе.

возможно, кто-то на самом деле уже делает это (возможно, веб-сервис), но я сомневаюсь в этом, если честно.

до сих пор я не видела. Но то, что я мог бы предложить для u, - это попытаться связать с Google calendar api, который оттуда пытается получить праздничный календарь через канал календаря или как бы вы его ни называли. Оттуда обработайте данные и, если хотите, сохраните их в своей базе данных. В конце концов, пока у вас есть активное подключение к интернету, вы можете использовать Java для подключения к соответствующим данным Даже для других языков, я не думаю, что такие прямые методы доступны.

public enum USFederalObservance {

  NEW_YEARS(rollWeekend(MonthDay.of(JANUARY, 1)::atYear)),

  MLK_DAY(nthDayOfWeekInMonth(3, MONDAY, JANUARY)),

  PRESIDENTS_DAY(nthDayOfWeekInMonth(3, MONDAY, FEBRUARY)),

  MEMORIAL_DAY(lastDayOfWeekInMonth(MONDAY, MAY)),

  INDEPENDENCE_DAY(rollWeekend(MonthDay.of(JULY, 4)::atYear)),

  LABOR_DAY(nthDayOfWeekInMonth(1, MONDAY, SEPTEMBER)),

  COLUMBUS_DAY(nthDayOfWeekInMonth(2, MONDAY, OCTOBER)),

  VETERANS_DAY(rollWeekend(MonthDay.of(NOVEMBER, 11)::atYear)),

  THANKSGIVING(nthDayOfWeekInMonth(4, THURSDAY, NOVEMBER)),

  CHRISTMAS(rollWeekend(MonthDay.of(DECEMBER, 25)::atYear));

  private Function<Integer, LocalDate> getObservance;

  USFederalObservance(Function<Integer, LocalDate> getObservance) {
    this.getObservance = getObservance;
  }

  public LocalDate atYear(int year) {
    return this.getObservance.apply(year);
  }
}


public class HolidayUtils {

  static Function<Integer, LocalDate> nthDayOfWeekInMonth(int n, DayOfWeek d, Month m) {
    return (Integer year) -> {
      var bom = LocalDate.of(year, m, 1);
      return bom.plusDays((7 - bom.getDayOfWeek().getValue() - d.getValue()) % 7);
    };
  }



  static Function<Integer, LocalDate> lastDayOfWeekInMonth(DayOfWeek d, Month m) {
    return (Integer year) -> {
      var eom = YearMonth.of(year, m).atEndOfMonth();
      return eom.minusDays((7 + eom.getDayOfWeek().getValue() - d.getValue()) % 7);
    };
  }

  static Function<Integer, LocalDate> rollWeekend(Function<Integer, LocalDate> func) {
    return (Integer year) -> {
      var date = func.apply(year);
      if (date.getDayOfWeek() == SATURDAY) {
        if (date.getDayOfYear() == 1) {
          return date.plusDays(2);
        }
        return date.minusDays(1);
      }
      if (date.getDayOfWeek() == SUNDAY) {
        return date.plusDays(1);
      }
      return date;
    };
  }
}

использование будет работать примерно так:

var newYears2018 = USFederalObservance.NEW_YEARS(2018);